MongoDb - $ match过滤器在子文档中不起作用

时间:2014-08-21 09:28:41

标签: node.js mongodb aggregation-framework subdocument

这是集合结构

[{
   "_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,
}

1 个答案:

答案 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操作,无论它是否满足条件。

所以一般来说你想做的是

  1. 匹配包含数组中所需元素的文档
  2. 展开匹配文件的数组
  3. 匹配排除所有其他内容所需的数组内容