Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
匹配MongoDB中数组中的每个对象_Mongodb_Mongodb Query_Aggregation Framework - Fatal编程技术网

匹配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中实际上引入了批量写入协议。您应该阅读添加到已接受答案中的注释,因为它遗漏了一些重要内容。