Mongodb foreach用于嵌套集合,以将文档更新/复制到另一个集合

时间:2015-11-25 08:00:15

标签: mongodb mongodb-query

我们收集了以下格式

{
    "_id" : ObjectId("5640bdec1b988de0be31724e"),     
    "xyz" : "Toshiba Satellite Pro 4600 PIII800",
    "Manufacture": "Toshiba"    
    "mappingData" : {       
        "title" : "xyz"  
    "brand" : "manufacture"     
    },
   "_id" : ObjectId("5640bdec1b9435dfgdf43554b"),     
    "abc" : "Apple Ihone",
    "mappingData" : {       
        "title" : "abc",
    "brand" : "Company"        
    }
}

我想编写查询并期望查询结果以创建包含以下文档的另一个集合。

{
 "title": "Toshiba Satellite Pro 4600 PIII800",
 "Manufacture":"Toshiba"        
}

{
 "title": "Apple Ihone",
 "Manufacture":"Apple"      
}

我形成了查询以获得预期结果但返回错误。

db.products.find().limit( 5 ).forEach(function(myDoc) { 
    var q = {};   
    myDoc.mappingData.array.forEach(function(doc){
        q[doc]= myDoc[myDoc.mappingData.doc];
        })  
     print(q);
//q will be inserted to new collection. 



})

返回错误"TypeError: myDoc.mappingData.array has no properties (shell):3"

请帮我解决此问题。

1 个答案:

答案 0 :(得分:0)

如果您要更新整个集合,则无需在当前代码中使用光标上的limit。您收到的错误是因为mappingData集合中的products字段没有名为array的子文档字段。从问题中的示例中,只有title子文档字段可用,而且这是您想要的字段。

根据产品集合的大小,将转换后的文档插入新集合可能会影响您的操作。您可以使用新的无序 bulk insert API 来避免插入性能下降,通过批量发送来简化插入操作,甚至更好,它会为您提供有关成功和失败的真实反馈。

以下批量插入API操作将向newcollection插入所需的数据结构,其中在产品集合光标的 forEach() 循环中创建新文档,使用 bracket notation 创建新属性。在批量插入中,您将以1000的批量将操作发送到服务器,这样可以提供更好的性能,因为您不是每次向服务器发送每个请求,而是每1000个请求中只有一次:

var bulk = db.newcollection.initializeUnorderedBulkOp(),   
    counter = 0;

db.products.find().forEach(function(doc) { 
    var document = {};
    if (doc.mappingData.title) document["title"] = doc[doc.mappingData.title];
    document["Manufacturer"] = doc.Manufacture;
    bulk.insert(document);
    counter++;
    if (counter % 1000 == 0) {
        bulk.execute();
        bulk = db.newcollection.initializeUnorderedBulkOp();
    }
});

if (counter % 1000 != 0) { bulk.execute(); }

通过上面的示例,您从批量API操作获得的反馈将采用以下格式:

BulkWriteResult({
    "writeErrors" : [ ],
    "writeConcernErrors" : [ ],
    "nInserted" : 2,
    "nUpserted" : 0,
    "nMatched" : 0,
    "nModified" : 0,
    "nRemoved" : 0,
    "upserted" : [ ]
})

查询新集合db.newcollection.find()将产生:

/* 0 */
{
    "_id" : ObjectId("56558b0427adb60c9f7e6f8d"),
    "title" : "Toshiba Satellite Pro 4600 PIII800",
    "Manufacturer" : "Toshiba"
}

/* 1 */
{
    "_id" : ObjectId("56558b0427adb60c9f7e6f8e"),
    "title" : "Apple Ihone",
    "Manufacturer" : undefined
}