如何使用批量读/写将每个文档的一部分转换为每个文档中的数组?

问题描述 投票:0回答:2

我有看起来像这样的文件

{
    "field1" : "value",
    "field3" : "value",
    "attributes" : {
        "key1" : {
            "category" : "4",
            "value" : "value"
        },
        "key2" : {
            "category" : "5",
            "value" : "value"
        },
    }
}

我想将它们转换为下面的结构(基本上是使用字典并将其展平为数组)。请注意,attributes中的键数有所不同。

{
    "field1" : "value",
    "field3" : "value",
    "attributes" : [
        {
            "key" : "key1",
            "category" : "4",
            "value" : "value"
        },
        {
            "key" : "key2",
            "category" : "5",
            "value" : "value"
        },
    ]
}

由于文档数量很大,所以我想使用批量API。我的脚本具有这个基本结构。

db = db.getSiblingDB('MyDB');

db.MyCollection.intializeOrderedBukOp(),
var bulk = db.MyCollection.intializeOrderedBukOp(),
    count = 0;

db.MyCollection.find({}).forEach(function(doc) {
   // Re-map attrs (what follows is some pseudocode
   var attrs = function TransformSomehow(doc.attributes) {
           // return an array...
       };
   });

   // Queue update operation
   bulk.find({ "_id": doc._id })
       .updateOne({ 
           "$set": { "attrs": attrs } }
       });
   count++;

   // Execute every 1000
   if ( count % 1000 == 0 ) {
       bulk.execute();
       bulk = db.collection.intializeOrderedBukOp();
   }
});

// Drain any queued remaining
if ( count % 1000 != 0 )
    bulk.execute();

这是从this answer借来的,但是我不能按原样使用它,因为它的方向相反(从数组到对象)。看来我无法使用map执行此操作。

arrays mongodb dictionary transformation bulkupdate
2个回答
1
投票

这是使用MongoDB NodeJS驱动程序v3.6和MongoDB v4.2.3进行批量写入的一种方法。这使用一个简单的批处理来更新所有收集文档。更新将每个文档的对象(或字典)转换为数组(根据您的要求)。

const collection = db.collection('test');

const update1 = { 
    updateMany: { 
        filter: { }, 
        update: [ 
            { $set: { 
                 attributes: { 
                     $map: { 
                         input: { $objectToArray: "$attributes" }, 
                         in: { $mergeObjects: [ { "key": "$$this.k" }, "$$this.v" ] } 
                     } 
                 } 
            } } 
        ] 
    } 
};

collection.bulkWrite( [ update1 ],
                      { ordered: false },
                      ( err, result ) => {
                          console.log( 'Updated and modified count: ', result.matchedCount, result.modifiedCount );
                       }
)

参考: CRUD Operations - Bulk Write


0
投票

@@ prasad_的答案有效。对于那些想要在没有NodeJS的MongoDB控制台中应用此功能的人,我将他的解决方案转换为此功能。

col = db.getCollection('X');

update1 = { 
    updateMany: { 
        filter: { }, 
        update: [ 
            { $set: { 
                 attributes: { 
                     $map: { 
                         input: { $objectToArray: "$attributes" }, 
                         in: { $mergeObjects: [ { "key": "$$this.k" }, "$$this.v" ] } 
                     } 
                 } 
            } } 
        ] 
    } 
}

col.bulkWrite( [ update1 ], { ordered: false })
© www.soinside.com 2019 - 2024. All rights reserved.