我想结合两个mongodb集合。
基本上我有一个包含从另一个集合引用一个文档的文档的集合。现在我希望将其作为内联/嵌套字段而不是单独的文档。
所以只是提供一个例子:
收藏A:
[{
"_id":"90A26C2A-4976-4EDD-850D-2ED8BEA46F9E",
"someValue": "foo"
},
{
"_id":"5F0BB248-E628-4B8F-A2F6-FECD79B78354",
"someValue": "bar"
}]
收集B:
[{
"_id":"169099A4-5EB9-4D55-8118-53D30B8A2E1A",
"collectionAID":"90A26C2A-4976-4EDD-850D-2ED8BEA46F9E",
"some":"foo",
"andOther":"stuff"
},
{
"_id":"83B14A8B-86A8-49FF-8394-0A7F9E709C13",
"collectionAID":"90A26C2A-4976-4EDD-850D-2ED8BEA46F9E",
"some":"bar",
"andOther":"random"
}]
这会导致集合A看起来像这样:
[{
"_id":"90A26C2A-4976-4EDD-850D-2ED8BEA46F9E",
"someValue": "foo",
"collectionB":[{
"some":"foo",
"andOther":"stuff"
},{
"some":"bar",
"andOther":"random"
}]
},
{
"_id":"5F0BB248-E628-4B8F-A2F6-FECD79B78354",
"someValue": "bar"
}]
答案 0 :(得分:1)
我在控制台上建议这样简单的东西:
db.collB.find().forEach(function(doc) {
var aid = doc.collectionAID;
if (typeof aid === 'undefined') { return; } // nothing
delete doc["_id"]; // remove property
delete doc["collectionAID"]; // remove property
db.collA.update({_id: aid}, /* match the ID from B */
{ $push : { collectionB : doc }});
});
循环遍历 collectionB 中的每个文档,如果定义了字段collectionAID
,则会删除不必要的属性(_id
和collectionAID
)。最后,它使用$push
运算符更新 collectionA 中的匹配文档,将文档从 B 添加到字段collectionB
。如果该字段不存在,则会自动将其创建为包含新插入文档的数组。如果它确实作为数组存在,它将被追加。 (如果它存在,但不是一个数组,它将失败)。由于update
来电未使用upsert
,因此如果 collectionB 文档中的_id
不存在,则不会发生任何事情。< / p>
您可以根据需要对其进行扩展以删除其他字段,或者如果 B 中的文档与 A 中的任何内容不匹配,则可能会添加更强大的错误处理
在您的数据上运行上面的代码会产生以下结果:
{ "_id" : "5F0BB248-E628-4B8F-A2F6-FECD79B78354", "someValue" : "bar" }
{ "_id" : "90A26C2A-4976-4EDD-850D-2ED8BEA46F9E",
"collectionB" : [
{
"some" : "foo",
"andOther" : "stuff"
},
{
"some" : "bar",
"andOther" : "random"
}
],
"someValue" : "foo"
}
答案 1 :(得分:0)
遗憾的是,mapreduce无法生成完整的文档。 https://jira.mongodb.org/browse/SERVER-2517
不知道为什么尽管有所有的关注,抱怨和赞成,他们还没有改变它。因此,您必须使用您选择的语言手动执行此操作。
希望您已将自己编入索引&#39; collectionAID&#39;这应该可以提高查询的速度。只需编写一次通过A集合一个文档的内容,加载_id然后从Collection B添加数组。
答案 2 :(得分:0)
比https://stackoverflow.com/a/22676205/1578508
快得多您可以反过来执行此操作并浏览要插入文档的集合。(更少执行!)
db.collA.find().forEach(function (x) {
var collBs = db.collB.find({"collectionAID":x._id},{"_id":0,"collectionA":0});
x.collectionB = collBs.toArray();
db.collA.save(x);
})