programing

mongodb 셸에서 각에 대한 업데이트 인

goodsources 2023. 7. 10. 22:18
반응형

mongodb 셸에서 각에 대한 업데이트 인

두 개의 레코드가 있는 테이블 컬렉션이 있습니다.

 {
    "title" : "record 1",
    "fields" : [ 
        {
            "_id" : 1,
            "items" : [ 
                1
            ]
        },
        {
            "_id" : 2,
            "items" : [ 
                2,3,4
            ]
        },
        {
            "_id" : 3,
            "items" : [ 
                5
            ]
        }
    ]
},

{
        "title" : "record 2",
        "fields" : [ 
            {
                "_id" : 4,
                "items" : [ 
                    7,8,9,10
                ]
            },
            {
                "_id" : 5,
                "items" : [ 

                ]
            },
            {
                "_id" : 6,
                "items" : [ 
                    11,12
                ]
            }
        ]
    }

다음에서 필드 aTable.fields.items를 업데이트합니다.

items : [ 11,12 ]

로.

items : [ 
   {item: 11, key: 0},
   {item:12, key: 0}
]

각 필드를 검색하지만 저장할 수 없습니다.

var t = db.aTable.find();

t.forEach(function( aRow ) {
    aRow.fields.forEach( function( aField ){
        aField.items.forEach( function( item ){
            var aNewItem = { item: parseInt(item), ref: 0 };
            db.aTable.update(item, {$set:aNewItem})
        } )
    } )
});

원하는 것을 얻으려면 다음과 같은 몇 가지가 필요합니다.

t.forEach(function( aRow ) {
    var newFields = [];
    aRow.fields.forEach( function( aField ){
        var newItems = [];
        aField.items.forEach( function( item ){
            var aNewItem = { item: parseInt(item), ref: 0 };
            newItems.push( aNewItem );
        } );
        newFields.push({ _id: aField._id, items: newItems });
    } )
    aTable.update(
        { _id: aRow._id }, 
        { "$set": { "fields": newFields } }
    );
});

따라서 기본적으로 업데이트하기 전에 어레이를 "재구성"해야 합니다.

전체 개체에서 직접 변경한 후 저장할 수 있습니다.다음 스니펫을 사용해 보십시오.

db.aTable.find().forEach(function (itemWrapper){
    itemWrapper.fields.forEach(function(field){
        var items = field.items;
        var newItems = [];
        items.forEach(function(item){
          var t = {'item':item,'key':0}
          newItems.push(t);      
        })
        field.items = newItems;
    })
    db.aTable.save(itemWrapper)
})

내가 하는 일은 모든 항목에 대해 반복하고 새로운 배열을 만드는 것입니다.{item : 1 , key:0}필드 개체의 항목 배열로 다시 설정합니다.

다음은 업데이트 후 출력입니다.

{
    "_id" : ObjectId("5332a192ece4ce8362c7a553"),
    "title" : "record 1",
    "fields" : [ 
        {
            "_id" : 1,
            "items" : [ 
                {
                    "item" : 1,
                    "key" : 0
                }
            ]
        }, 
        {
            "_id" : 2,
            "items" : [ 
                {
                    "item" : 2,
                    "key" : 0
                }, 
                {
                    "item" : 3,
                    "key" : 0
                }, 
                {
                    "item" : 4,
                    "key" : 0
                }
            ]
        }, 
        {
            "_id" : 3,
            "items" : [ 
                {
                    "item" : 5,
                    "key" : 0
                }
            ]
        }
    ]
}

/* 1 */
{
    "_id" : ObjectId("5332a192ece4ce8362c7a554"),
    "title" : "record 2",
    "fields" : [ 
        {
            "_id" : 4,
            "items" : [ 
                {
                    "item" : 7,
                    "key" : 0
                }, 
                {
                    "item" : 8,
                    "key" : 0
                }, 
                {
                    "item" : 9,
                    "key" : 0
                }, 
                {
                    "item" : 10,
                    "key" : 0
                }
            ]
        }, 
        {
            "_id" : 5,
            "items" : []
        }, 
        {
            "_id" : 6,
            "items" : [ 
                {
                    "item" : 11,
                    "key" : 0
                }, 
                {
                    "item" : 12,
                    "key" : 0
                }
            ]
        }
    ]
}

시작하는Mongo 4.2집계db.collection.update() 파이프라인을 수락하여 최종적으로 현재 값을 기반으로 필드를 업데이트할 수 있으므로 Javascript 대신 쿼리를 사용할 수 있습니다.

// {
//   title: "record 1",
//   fields: [
//     { _id: 1, items: [1] },
//     { _id: 2, items: [2, 3, 4] },
//     { _id: 3, items: [5] }
//   ]
// }
db.collection.updateMany(
  {},
  [{ $set: {
       fields: { $map: {
         input: "$fields",
         as: "x",
         in: {
           _id: "$$x._id",
           items: { $map: {
             input: "$$x.items",
             as: "y",
             in: { item: "$$y", key: 0 }
           }}
         }
       }}
  }}]
)
// {
//   title: "record 1",
//   fields: [
//     { _id: 1, items: [ { item: 1, key: 0 } ] },
//     { _id: 2, items: [ { item: 2, key: 0 }, { item: 3, key: 0 }, { item: 4, key: 0 } ] },
//     { _id: 3, items: [ { item: 5, key: 0 } ] }
//   ]
// }
  • 첫 번째 파트{}업데이트할 문서(이 경우 모든 문서)를 필터링하는 일치 쿼리입니다.

  • 제2부[{ $set: { fields: { $map: { ... } } }]업데이트 집계 파이프라인입니다(집계 파이프라인 사용을 나타내는 대괄호 참조).

  • $set 이 경우 필드 값을 대체하는 새 집계 연산자입니다.

  • 그런 다음(보일러 플레이트를 통과하면) 중첩된 두 배열을 ping합니다.

  • 보다 구체적으로, 두 번째 맵 변환은 다음을 대체합니다.[1, 2]타고[{ item: 1, key: 0 }, { item: 2, key: 0 }].

언급URL : https://stackoverflow.com/questions/22656517/update-in-foreach-on-mongodb-shell

반응형