programing

mongodb에서 중첩된 배열 업데이트 중

testmans 2023. 5. 25. 21:36
반응형

mongodb에서 중첩된 배열 업데이트 중

mongodb에 업데이트해야 하는 객체의 2단계 심층 중첩 배열이 있는 문서가 있습니다.

{
    id: 1,
    items: [
        {
            id: 2,
            blocks: [
                {
                    id: 3
                    txt: 'hello'
                }
            ]
        }
    ] 
}

레벨 딥 배열이 하나만 있으면 위치 연산자를 사용하여 개체를 업데이트할 수 있지만, 두 번째 레벨에서는 다음과 같이 중첩된 개체의 인덱스가 있는 위치 연산자를 사용하는 것이 유일한 방법입니다.

db.objects.update({'items.id': 2}, {'$set': {'items.$.blocks.0.txt': 'hi'}})

이 접근 방식은 효과가 있지만 웹 서비스를 구축하는 중이고 인덱스 번호는 인덱스로 100000을 보낼 수 있는 클라이언트에서 와야 하기 때문에 위험해 보입니다. 그러면 mongodb는 null 값의 인덱스 100000을 가진 배열을 만들어야 합니다.

이러한 중첩된 개체를 업데이트하여 위치 대신 개체의 ID를 참조하거나 쿼리에서 사용하기 전에 제공된 인덱스가 범위를 벗어났는지 확인할 수 있는 다른 방법이 있습니까?

여기 중요한 질문이 있습니다. Mongo의 "addToSet" 및 "push" 작업을 활용해야 합니까?어레이에서 개별 항목만 수정할 계획이라면 이러한 어레이를 개체로 빌드해야 합니다.

이를 구성하는 방법은 다음과 같습니다.

{
    id: 1,
    items: 
        { 
          "2" : { "blocks" : { "3" : { txt : 'hello' } } },
          "5" : { "blocks" : { "1" : { txt : 'foo'}, "2" : { txt : 'bar'} } }
        }
}

이것은 기본적으로 모든 것을 배열이 아닌 JSON 개체로 변환합니다.사용할 수 없게 됩니다.$push그리고.$addToSet이렇게 하면 모든 게 쉬워질 것 같아요예를 들어 쿼리는 다음과 같습니다.

db.objects.update({'items.2': {$exists:true} }, {'$set': {'items.2.blocks.0.txt': 'hi'}})

제가 "ID"를 버렸다는 것도 알게 될 것입니다.이와 같은 것을 중첩할 때 일반적으로 "ID"를 해당 숫자를 인덱스로 사용하는 것으로 대체할 수 있습니다.이제 "ID" 개념이 암시됩니다.

이 기능은 표현식 업데이트와 함께 3.6에 추가되었습니다.

db.objects.update( {id: 1 }, { $set: { 'items.$[itm].blocks.$[blk].txt': "hi", } }, { multi: false, arrayFilters: [ { 'itm.id': 2 }, { 'blk.id': 3} ] } )

사용 중인 ID는 선형 번호이며 'max_idx'와 같은 추가 필드 또는 유사한 필드에서 와야 합니다.즉, ID를 한 번 조회한 다음 업데이트합니다.UUID/ObjectId는 ID에 사용할 수 있으므로 분산 CRUD도 사용할 수 있습니다.

게이츠의 답변을 바탕으로 중첩된 객체 배열에서 작동하는 솔루션을 고안했습니다.

db.objects.updateOne({
  ["items.id"]: 2
}, {
  $set: {
    "items.$.blocks.$[block].txt": "hi",
  },
}, {
  arrayFilters: [{
    "block.id": 3,
  }],
});

MongoDB 3.6은 모든 위치 연산자 $[]추가하여 업데이트가 필요한 블록의 ID를 알고 있다면 다음과 같은 작업을 수행할 수 있습니다.

db.objects.update({'items.blocks.id': id_here}, {'$set': {'items.$[].blocks.$.txt': 'hi'}})

db.col.update({"items.blocks.id": 3},
{ $set: {"items.$[].blocks.$[b].txt": "bonjour"}},
{ arrayFilters: [{"b.id": 3}] }
)

https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/ #update-messages-messages-unction-with

이것은 다음을 위한 피몬고 함수입니다.find_one_and_update저는 피몬고 기능을 찾기 위해 많이 검색했습니다..

find_one_and_update(filter, update, projection=None, sort=None, return_document=ReturnDocument.BEFORE, array_filters=None, hint=None, session=None, **kwargs)

db.pymongo_object.find_one_and_update( filter = {'id' : 1}, update= {$set: {"items.$[array1].blocks.$[array2].txt": "hi"}}, array_filters =[{"array1.id" :2}, {"array2.id": 3}]) 

Pymongo 설명서도 참조하십시오.

언급URL : https://stackoverflow.com/questions/4121666/updating-nested-arrays-in-mongodb

반응형