Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.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 聚合期间在mongo中自定义组_Mongodb - Fatal编程技术网

Mongodb 聚合期间在mongo中自定义组

Mongodb 聚合期间在mongo中自定义组,mongodb,Mongodb,我使用的是mongo docs中的一个例子,我做了一些修改: db.books.aggregate( [ { $group : { _id : "$genre", books: { $push: "$$ROOT" } } } ] ) 此查询将按流派返回书籍数组 我想定制一点,这样我就不会得到额外的数据。下面的示例可能是一个虚拟示例,但我很好奇它是否可以在mongo中实现。我希望我的聚合返回一个组数组,其中如果genre是“悲剧”,则只提取一本书,并且将有一个booksCo

我使用的是mongo docs中的一个例子,我做了一些修改:

db.books.aggregate(
   [
     { $group : { _id : "$genre", books: { $push: "$$ROOT" } } }
   ]
)
此查询将按流派返回书籍数组

我想定制一点,这样我就不会得到额外的数据。下面的示例可能是一个虚拟示例,但我很好奇它是否可以在mongo中实现。我希望我的聚合返回一个组数组,其中如果
genre
是“悲剧”,则只提取一本书,并且将有一个
booksCount
字段,在所有其他情况下
books
将是一个数组,而不会有
booksCount

因此,聚合结果如下所示:

[
  { _id: '_id of tragedy genre', book: {some book}, booksCount: some int },
  { _id: '_id of some other genre', books: [books] },
  ...
]

因此,我希望组根据某些条件具有不同的键,一种方法是使用聚合管道阶段。此阶段允许我们使用相同的输入文档创建多个管道。在这种情况下,我们有一个管道用于悲剧类型,另一个管道用于所有其他类型。为了获得您想要的输出,我们需要合并两个管道阶段。从文档中:

每个子管道在输出文档中都有自己的字段,其结果存储为文档数组

因为facet阶段为每个管道返回一个文档数组,所以我们需要:将这些数组连接在一起,展开生成的数组,使每个元素都是自己的文档,然后替换每个文档的根以除去不需要的键

实例 假设您拥有以下文档:

db.books.insertMany([{
    genre: "Tragedy",
    title: "Romeo and Juliet"
}, {
    genre: "Tragedy",
    title: "Titanic"
}, {
    genre: "Comedy",
    title: "Hitchhikers Guide to the Galaxy"
}, {
    genre: "Comedy",
    title: "Blazing Saddles"
}, {
    genre: "Thriller",
    title: "Shutter Island"
}, {
    genre: "Thriller",
    title: "Hannibal"
}])
然后可以使用以下查询:

db.books.aggregate([{
    $facet: {
        tragedy: [{
            $match: {genre: "Tragedy"}
        }, {
            $group: {
                _id: "$genre",
                books: {$push: "$$ROOT"}
            }
        }, {
            $project: {
                book: {$arrayElemAt: ["$books", 1]},
                booksCount: {$size: "$books"}
            }
        }],
        other: [{
            $match: {
                genre: {$ne: "Tragedy"}
            } 
        }, {
            $group: {
                _id: "$genre",
                books: {$push: "$$ROOT"}
            }
        }]
    }
}, {
    $project: {
        documents: {$concatArrays: ["$tragedy", "$other"]}  
    }
}, {
    $unwind: "$documents"
}, {
    $replaceRoot: {newRoot: "$documents"}
}])
制作:

{
    "_id" : "Tragedy",
    "book" : {
        "_id" : ObjectId("5c59f15bc59454560b36a5c7"),
        "genre" : "Tragedy",
        "title" : "Titanic"
    },
    "booksCount" : 2
}
{
    "_id" : "Thriller",
    "books" : [
        {
            "_id" : ObjectId("5c59f15bc59454560b36a5ca"),
            "genre" : "Thriller",
            "title" : "Shutter Island"
        },
        {
            "_id" : ObjectId("5c59f15bc59454560b36a5cb"),
            "genre" : "Thriller",
            "title" : "Hannibal"
        }
    ]
}
{
    "_id" : "Comedy",
    "books" : [
        {
            "_id" : ObjectId("5c59f15bc59454560b36a5c8"),
            "genre" : "Comedy",
            "title" : "Hitchhikers Guide to the Galaxy"
        },
        {
            "_id" : ObjectId("5c59f15bc59454560b36a5c9"),
            "genre" : "Comedy",
            "title" : "Blazing Saddles"
        }
    ]
}