Mongodb将多个对象转换为数组,就地,永久 [英] Mongodb convert multiple objects to an array, in place, permanently

查看:59
本文介绍了Mongodb将多个对象转换为数组,就地,永久的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含这种形式的文档的集合:

I have a collection with documents in this form:

{
    "name" : "John Smith",    
    "store_affiliation" : {
        "stores" : {
            "ABCD" : {
                "role" : "General Manager", 
                "startdate" : ISODate("1970-01-01T00:00:00.000+0000"), 
                "enddate" : ISODate("1980-01-01T00:00:00.000+0000"), 
                "permissions" : "GM"
            }, 
            "1234" : {
                "role" : "Owner", 
                "startdate" : ISODate("1970-01-01T00:00:00.000+0000"), 
                "enddate" : null, 
                "permissions" : "ALL"
            }, 
            "4321" : {
                "role" : "Owner", 
                "startdate" : ISODate("1990-01-01T00:00:00.000+0000"), 
                "enddate" : null, 
                "permissions" : "ALL"
            }
        }
}

...但我需要商店列表采用这种形式(商店"数组):

...but I need the list of stores to be in this form (an array of "stores"):

{ "name" : "John Smith",
  "store_affiliation" : {
        "stores" : [
            {
                "store_code" : "ABCD", 
                "role" : "General Manager", 
                "startdate" : ISODate("1970-01-01T00:00:00.000+0000"), 
                "enddate" : ISODate("1980-01-01T00:00:00.000+0000"), 
                "permissions" : "GM"
            }, 
            {
                "store_code" : "1234", 
                "role" : "Owner", 
                "startdate" : ISODate("1970-01-01T00:00:00.000+0000"), 
                "enddate" : null, 
                "permissions" : "ALL"
            }, 
            {
                "shop_id" : "4321", 
                "role" : "Owner", 
                "startdate" : ISODate("1990-01-01T00:00:00.000+0000"), 
                "enddate" : null, 
                "permissions" : "ALL"
            }
        ]
}

我研究过在 aggregate 管道中使用 $project$group$push,但我感觉使用 aggregate 甚至可能是死路一条,因为我不是在查询结果;我正在尝试永久修改集合中的每个文档(数千个).

I have researched using $project, $group and $push in an aggregate pipeline, but I feel like using aggregate may even be a dead end, because I'm not after a query result; I'm trying to modify every document (thousands) in the collection permanently.

推荐答案

您可以在 3.4 版本中尝试以下聚合管道.

You can try below aggregation pipeline in 3.4 version.

下面的聚合使用 stores 嵌入文档更改为键值对数组rel="nofollow noreferrer">$objectToArray 后跟 $map 输出带有新字段的转换数组,同时保留所有现有字段.

Below aggregation changes the stores embedded document into array of key value pairs using $objectToArray followed by $map to output transformed array of with new field while keeping all the existing fields.

批量更新以编写新的商店结构.

Bulk update to write the new stores structure.

var bulk = db.getCollection(col).initializeUnorderedBulkOp();
var count = 0;
var batch = 1;

db.getCollection(col).aggregate([
{"$match":{"store_affiliation.stores":{"$ne":{"$type":4}}}},
{"$addFields":{
  "stores":{
      "$map":{
        "input":{"$objectToArray": "$store_affiliation.stores"}, 
        "in":{
           "store_code":"$$this.k", 
           "role":"$$this.v.role", 
           "startdate":"$$this.v.startdate", 
           "enddate":"$$this.v.enddate", 
           "permissions":"$$this.v.permissions"
         }
      }
    }
}}]).forEach(function(doc){ 
    var _id = doc._id; 
    var stores = doc.stores; 
    bulk.find({ "_id" : _id }).updateOne(
      { $set: {"store_affiliation.stores" : stores} }
   ); 
    count++;  
    if (count == batch) { 
        bulk.execute(); 
        bulk = db.getCollection(col).initializeUnorderedBulkOp(); 
        count = 0;
    } 
});

if (count > 0) { 
    bulk.execute(); 
}

这篇关于Mongodb将多个对象转换为数组,就地,永久的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆