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