这是集合结构
[{
"_id" : "....",
"name" : "aaaa",
"level_max_leaves" : [
{
level : "ObjectIdString 1",
max_leaves : 4,
}
]
},
{
"_id" : "....",
"name" : "bbbb",
"level_max_leaves" : [
{
level : "ObjectIdString 2",
max_leaves : 2,
}
]
}]
我需要找到level_max_leaves.level
过滤器的子文档值,当它与给定的输入值匹配时。
这就是我的尝试,
For example,
var empLevelId = 'ObjectIdString 1' ;
MyModel.aggregate(
{$unwind: "$level_max_leaves"},
{$match: {"$level_max_leaves.level": empLevelId } },
{$group: { "_id": "$level_max_leaves.level",
"total": { "$sum": "$level_max_leaves.max_leaves" }}},
function (err, res) {
console.log(res);
});
但是$match
过滤器无效。我无法找到ObjectIdString 1
如果我使用name
字段进行过滤,则其工作正常。像这样,
{$match: {"$name": "aaaa" } },
但是在子文档级别,它返回0
。
{$match: {"$level_max_leaves.level": "ObjectIdString 1"} },
我的预期结果是,
{
"_id" : "ObjectIdString 1",
"total" : 4,
}
答案 0 :(得分:0)
您输错了$match
。带有$
前缀的字段可以是已实现的运算符,也可以是对字段内容的“变量”引用。所以你只需输入字段名称:
MyModel.aggregate(
[
{ "$match": { "level_max_leaves.level": "ObjectIdString 1" } },
{ "$unwind": "$level_max_leaves" },
{ "$match": { "level_max_leaves.level": "ObjectIdString 1" } },
{ "$group": {
"_id": "$level_max_leaves.level",
"total": { "$sum": "$level_max_leaves.max_leaves" }
}}
],
function (err, res) {
console.log(res);
}
);
您提供的样本中包含哪些内容:
{ "_id" : "ObjectIdString 1", "total" : 4 }
在您的管道中首先$match
也是一种好习惯。事实上,这是唯一可以使用索引的时间。但不仅仅是因为没有初始$match
语句,您的聚合管道将对集合中的每个文档执行$unwind
操作,无论它是否满足条件。
所以一般来说你想做的是