匹配MongoDB中数组中的每个对象
我有一个作者集,看起来像这样:匹配MongoDB中数组中的每个对象,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有一个作者集,看起来像这样: { "_id" : ObjectId("332ddf"), "authors" : "Mark Twain", "publisher" : "NY", "books" : [ "The Adventures of Tom Sawyer", "The Prince and the Pauper" ] } { "_id" : ObjectId("4ef342"), "authors" : "F. Scott Fitzgerald", "
{ "_id" : ObjectId("332ddf"),
"authors" : "Mark Twain",
"publisher" : "NY",
"books" : [ "The Adventures of Tom Sawyer", "The Prince and the Pauper" ] }
{ "_id" : ObjectId("4ef342"),
"authors" : "F. Scott Fitzgerald",
"publisher" : "NY",
"books" : [ "The Adventures of Tom Sawyer",
"The Great Gatsby", "This Side of Paradise" ] }
我正在尝试使用聚合创建一个新集合。对于聚合,我尝试了:
db.author.aggregate([
{ "$unwind": "$books"},
{ $project:
{
book: "$books",
authors: ["$authors"]
}
}
])
但是我得到了
重复键错误集合
,用于展开书籍。如何使用聚合获得所需的集合?实际上,您不需要$project
阶段。您所需要做的就是使用操作符“反规范化”“Books”数组,然后使用“book”将文档“反规范化”,并使用操作符返回“authors”数组
var cursor=db.getCollection('authors').aggregate([
{“$unwind”:“$BOOTKS”},
{“$group”:{
“_id”:“$books”,
“作者”:{“$push”:“$authors”}
}}
])
聚合查询产生如下结果:
{“\u id”:“天堂的这一边”,“作者”:[“F.斯科特·菲茨杰拉德]}
{u id:“伟大的盖茨比”,“作家”:[“F.斯科特·菲茨杰拉德]}
{“_id”:“王子与穷人”,“作者”:[“马克·吐温”]}
{
“_id”:“汤姆·索耶历险记”,
“作者”:[
“马克吐温”,
“F.斯科特·菲茨杰拉德”
]
}
顺便说一句,您预期结果中的\u id
复合字段没有多大意义,因此我删除了它,但如果您确实觉得需要它,那么只需在分组阶段将“\id”:“$books”
替换为“\id”:{“book”:“$books”}
现在让我们看看如何插入到另一个集合中。一种方法是使用操作符,这必须是聚合管道中的最后一个阶段
{“$out”:“newCollection”}
如果在将文档插入新集合之前需要在客户端处理结果,则应使用“批量”操作
MongoDB 3.2或更新版本
var请求=[];
var计数=0;
cursor.forEach(函数(文档){
//对文档执行某些操作并将新操作推送到堆栈中
push({insertOne:document});
计数++;
如果(计数%1000==0){
db.newCollection.bulkWrite(请求);
请求=[];
计数=0;
}
});
db.newCollection.bulkWrite(请求);
MongoDB 3.0向后
var bulk=db.newCollection.initializeUnderedBulkop();
var计数=0;
cursor.forEach(函数(文档){
//对文档执行某些操作并将新操作推送到堆栈中
批量。插入(文件);
计数++;
如果(计数%1000==0){
bulk.execute();
bulk=db.newCollection.initializeUnderedBulkop();
}
})
如果(计数>0){
bulk.execute();
}
实际上,对于OP来说,最好使用它,因为它只是直接在服务器上写入集合。因为在客户端没有什么可做的,所以通过网络撤回所有文档并重写它们是没有意义的。MongoDB 2.6中实际上引入了批量写入协议。您应该阅读添加到已接受答案中的注释,因为它遗漏了一些重要内容。