prosource

MongoDB 문서에서 이중 중첩 배열에서 요소를 제거하는 방법

probook 2023. 5. 18. 21:07
반응형

MongoDB 문서에서 이중 중첩 배열에서 요소를 제거하는 방법

다음과 같은 문서 구조를 가지고 있습니다.

{
"_id" : "777",
"someKey" : "someValue",
"someArray" : [
    {
        "name" : "name1",
        "someNestedArray" : [
            {
                "name" : "value"
            },
            {
                "name" : "delete me"
            }
        ]
    }
  ]
}

"delete me" 값으로 중첩된 배열 요소를 삭제합니다.

중첩을 사용하여 이 설명과 일치하는 문서를 찾을 수 있음을 알고 있습니다.$elemMatch표현.문제의 요소를 제거하기 위한 쿼리 구문은 무엇입니까?

문제의 항목을 삭제하려면 실제로 업데이트를 사용합니다.좀 더 구체적으로 말하면, 당신은 그것으로 업데이트를 할 것입니다.$pull배열에서 항목을 제거하는 명령입니다.

db.temp.update(
  { _id : "777" },
  {$pull : {"someArray.0.someNestedArray" : {"name":"delete me"}}}
)

여기에 약간의 "마법"이 일어나고 있습니다.사용..0우리가 0번째 항목을 수정하고 있다는 것을 나타냅니다.someArray.사용.{"name":"delete me"}제거하려는 정확한 데이터를 알고 있음을 나타냅니다.

이 프로세스는 데이터를 클라이언트에 로드한 다음 업데이트를 수행하는 경우에 잘 작동합니다.이러한 작업을 수행하는 "일반" 쿼리를 수행하려는 경우에는 이 프로세스가 제대로 작동하지 않습니다.

하위 문서의 배열을 업데이트하려면 일반적으로 어느 시점에 원본을 메모리에 저장해야 한다는 것을 간단히 인식하는 것이 가장 쉽습니다.


아래의 첫 번째 의견에 대응하여, 당신은 아마도 데이터 구조를 약간 변경함으로써 당신의 상황을 도울 수 있을 것입니다.

"someObjects" : {
  "name1":  {
        "someNestedArray" : [
            {
                "name" : "value"
            },
            {
                "name" : "delete me"
            }
        ]
    }
}

이제 할 수 있습니다.{$pull : { "someObjects.name1.someNestedArray" : ...

여기 당신의 구조의 문제가 있습니다.MongoDB는 "하위 배열"을 조작하는 것을 매우 잘 지원하지 않습니다.구조에는 개체의 배열이 있고 이러한 개체에는 더 많은 개체의 배열이 있습니다.

만약 당신이 다음과 같은 구조를 가지고 있다면, 당신은 다음과 같은 것들을 사용하는데 어려움을 겪을 것입니다.$pull:

array [
  { subarray : array [] },
  { subarray : array [] },
]

구조가 그렇게 보이고 업데이트하려는 경우subarray두 가지 옵션이 있습니다.

  1. 활용할 수 있도록 구조 변경$pull.
  2. 사용 안 함$pull전체 개체를 클라이언트에 로드하고 사용findAndModify.

MongoDB 3.6은 내장된 문서를 포함하는 배열에 대한 업데이트를 용이하게 하는 연산자를 추가했습니다.따라서 다음을 통해 문제를 해결할 수 있습니다.

db.test.update(
  { _id : "777" },
  {$pull : {"someArray.$[].someNestedArray" : {"name":"delete me"}}}
)

@Melkor가 언급했듯이 (아마도 답은 그 자체일 것입니다)

인덱스를 모르는 경우 다음을 사용합니다.

{
    _id: TheMainID, 
    "theArray._id": TheArrayID
},
{
    $pull: {
        "theArray.$.theNestedArray": {
            _id: theNestedArrayID
        }
    }
}

MongoDB 3.6에서 사용할 수 있습니다.arrayFilters수행 방법:

db.test.update(
  { _id: "777" }, 
  { $pull: { "someArray.$[elem].someNestedArray": { name: "delete me" } } },
  { arrayFilters: [{ "elem.name": "name1"}] }
)

참고 항목: https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/index.html#update-all-documents-that-match-arrayfilters-in-an-array

다른 예와 용도는 다음과 같습니다.

{

    "company": {
        "location": {
            "postalCode": "12345",
            "Address": "Address1",
            "city": "Frankfurt",
            "state": "Hessen",
            "country": "Germany"
        },
        "establishmentDate": "2019-04-29T14:12:37.206Z",
        "companyId": "1",
        "ceo": "XYZ"
    },
    "items": [{
            "name": "itemA",
            "unit": "kg",
            "price": "10"
        },
        {
            "name": "itemB",
            "unit": "ltr",
            "price": "20"
        }

    ]
}
  1. DELETE : Mongodb 항목 B를 삭제하기 위한 쿼리:
db.getCollection('test').update(   
    {"company.companyId":"1","company.location.city":"Frankfurt"},
    {$pull : {"items" : {"name":"itemB"}}}
)
  1. 찾기: 항목 B에 대한 쿼리 찾기:
db.getCollection('test').find(
    {"company.companyId":"1","company.location.city":"Frankfurt","items.name":"itemB"},
    { "items.$": 1 }
)

3.UPDATE : 항목 B에 대한 업데이트 쿼리:

db.getCollection('test').update
(
 {"company.companyId":"1","company.location.city":"Frankfurt","items.name":"itemB"},
 { $set: { "items.$[].price" : 90 }}, 
   { multi: true });

언급URL : https://stackoverflow.com/questions/5228210/how-to-remove-an-element-from-a-doubly-nested-array-in-a-mongodb-document

반응형