...并通过过滤器标准减少子文档?
我有以下数据结构
{
"_id" : "PwS8gcfhaWLaudjaJ",
"name" : "Name of Document 1",
"subdocuments" : [
{
"subdocumentsId" : "dqR9gPi7tNvzpEhEW",
"number" : 1
},
{
"subdocumentsId" : "vTaPoQYdaDbqMH7Pg",
"number" : 1
},
{
"subdocumentsId" : "tPJ45KqAzvFPBRstZ",
"number" : 3
}
]
}
{
"_id" : "PwS8gcfhaWLaudjaJ",
"name" : "Name of Document 2",
"subdocuments" : [
{
"subdocumentsId" : "dqR9gPi7tNvzpEhEW",
"number" : 2
},
{
"subdocumentsId" : "tPJ45KqAzvFPBRstZ",
"number" : 5
}
]
}
如何构建查询以获得以下结果
{
"_id" : "PwS8gcfhaWLaudjaJ",
"name" : "Name of Document 2",
"subdocuments" : [
{
"subdocumentsId" : "dqR9gPi7tNvzpEhEW",
"number" : 2
},
{
"subdocumentsId" : "tPJ45KqAzvFPBRstZ",
"number" : 5
}
]
}
{
"_id" : "PwS8gcfhaWLaudjaJ",
"name" : "Name of Document 1",
"subdocuments" : [
{
"subdocumentsId" : "dqR9gPi7tNvzpEhEW",
"number" : 1
},
{
"subdocumentsId" : "tPJ45KqAzvFPBRstZ",
"number" : 3
}
]
}
...这是我当前的查询
var filterIds = ['dqR9gPi7tNvzpEhEW','tPJ45KqAzvFPBRstZ'];
db.Documents
.aggregate([
{
$match: {
'subdocuments.subdocumentsId': {
$in: filterIds
}
}
}, {
$project: {
_id: 1,
name: 1,
totalNumber: {
$sum: '$subdocuments.number'
}
}
}, {
$sort: {
totalNumber: 1
}
}
])
我无法在$ project-operation中使用$ sum-expression。它仅适用于$ group。
是否有共同的解决方法,或者是否可以使用$ group获得结果?
也许有人可以帮忙吗?
答案 0 :(得分:1)
使用数组时需要使用$unwind
。此外,您还有两个$group
操作,其间有$sort
:
db.Documents.aggregate([
// Select documents
{ "$match": {
"subdocuments.subdocumentsId": {
"$in": filterIds
}
}},
// Denormalize array
{ "$unwind": "subdocuments" }
// Filter array elements
{ "$match": {
"subdocuments.subdocumentsId": {
"$in": filterIds
}
}},
// Get array sum
{ "$group": {
"_id": {
"_id": "$_id",
"name": "$name",
"subId": "$subdocuments.subdocumentsId"
},
"number": { "$sum": "$subdocuments.number" }
}},
// Sort the results
{ "$sort": { "_id._id": 1, "number": 1 } },
// Group back to documents
{ "$group": {
"_id": "$_id._id",
"name": { "$first": "$_id.name" },
"subdocuments": { "$push": {
"subdocumentsId": "$_id.subId",
"number": "$number"
}},
"total": { "$sum": "$number" }
}},
// Sort at the end, decending for largest first
{ "$sort": { "total": -1 } }
])
如果您通过其uinique“subdocumentId”值“汇总”过滤结果,那么这些值不是唯一的。如果您只是过滤,请减少步骤:
db.Documents.aggregate([
// Select documents
{ "$match": {
"subdocuments.subdocumentsId": {
"$in": filterIds
}
}},
// Denormalize array
{ "$unwind": "subdocuments" }
// Filter array elements
{ "$match": {
"subdocuments.subdocumentsId": {
"$in": filterIds
}
}},
// Group back to documents
{ "$group": {
"_id": "$_id",
"name": { "$first": "$name" },
"subdocuments": {
"$push": "$subdocuments"
},
"total": { "$sum": "$subdocuments.number" }
}},
// Sort at the end, decending for largest first
{ "$sort": { "total": -1 } }
])
答案 1 :(得分:1)
请尝试以下查询:
以下是获取结果所遵循的步骤:
1)展开您的子文档
2)仅保留与过滤器" filterIds匹配的文档 "标准
3)根据_id字段对文档进行分组,并保留" subdocuments.number"的总和。字段,以便我们可以根据它进行排序。
4)根据" subdocuments.number"进行排序。 field(tot)按降序排列。
5)最终以您需要的格式进行投影或显示。
db.Documents.aggregate([
{
$unwind:"$subdocuments"
},
{
$match:{"subdocuments.subdocumentsId" : {"$in" : filterIds }}
},
{
$group:{ _id : { id : "$_id", name :"$name" },
tot : { "$sum": "$subdocuments.number"} ,
subdocuments : {"$push" :
{subdocumentsId:"$subdocuments.subdocumentsId",
number : "$subdocuments.number" } } } },
{
$sort:{tot : -1}
},
{
$project:{_id:"$_id.id", name: "$_id.name", subdocuments:1}
}
]).pretty();
因此上面的查询会获取所需的结果(OUTPUT):
{
"_id" : "PwS8gcfhaWLaudjaI",
"subdocuments" : [
{
"subdocumentsId" : "dqR9gPi7tNvzpEhEW",
"number" : 2
},
{
"subdocumentsId" : "tPJ45KqAzvFPBRstZ",
"number" : 5
}
],
"name" : "Name of Document 2"
}
{
"_id" : "PwS8gcfhaWLaudjaJ",
"subdocuments" : [
{
"subdocumentsId" : "dqR9gPi7tNvzpEhEW",
"number" : 1
},
{
"subdocumentsId" : "tPJ45KqAzvFPBRstZ",
"number" : 3
}
],
"name" : "Name of Document 1"
}