如何在聚合投影中使用$ elemMatch?

问题描述 投票:8回答:6

这是我的目标:

{ "_id" : ObjectId("53fdcb6796cb9b9aa86f05b9"), "list" : [ "a", "b" ], "complist" : [ { "a" : "a", "b" : "b" }, { "a" : "c", "b" : "d" } ] }

这就是我想要完成的事情:检查“list”是否包含某个元素,并在读取文档时从“complist”上的对象中仅获取字段“a”,而不管这些值是什么。我正在构建一个论坛系统,这是将返回论坛详细信息的查询。我需要在知道用户是否在论坛的白名单中时阅读论坛信息。

有了查找,我可以使用查询

db.itens.find({},{list:{$elemMatch:{$in:["a"]}}})

仅获取匹配特定值的第一个元素。这样我就可以检查返回的数组是否为空,我知道“list”是否包含我正在寻找的值。我无法在查询上执行此操作,因为我想要文档,无论它包含我在“list”值中寻找的值。我需要文档并知道“list”是否具有某个值。

使用聚合我可以使用查询

db.itens.aggregate({$project:{"complist.a":1}})

只读取complist中包含的对象的字段“a”。这将获得论坛的线程基本信息,我不想要线程的所有信息,只是一些事情。

但是当我尝试使用查询时

db.itens.aggregate({$project:{"complist.b":1,list:{$elemMatch:{$in:["a"]}}}})

尝试做两件事,它会抛出一个错误,说操作符$ elemMatch无效。

我在这里用$ elemMatch做错了吗?有没有更好的方法来实现这一目标?

mongodb projection
6个回答
8
投票

出于某种原因,$ elemMatch在聚合中不起作用。您需要在Mongo 3.2中使用新的$ filter运算符。见https://docs.mongodb.org/manual/reference/operator/aggregation/filter/


6
投票

实际上,最简单的解决方案是只需$展开你的数组,然后$匹配相应的文档。您可以使用$ group和$ push再次关闭相应的文档。


4
投票

this question的答案可能有所帮助。

db.collection_name.aggregate({
    "$match": {
        "complist": {
            "$elemMatch": {
                "a": "a"
            }
        }
    }
});

1
投票

虽然这个问题很老,但这是我2017年11月的贡献。

我有类似的问题,连续两次比赛操作为我工作。下面的代码是我整个代码的一个子集,我更改了元素名称,所以它没有经过测试。无论如何,这应该指向正确的方向。

db.collection.aggregate([
    {
        "$match": {
            "_id": "ID1"
        }
    },
    {
        "$unwind": "$sub_collection"
    },
    {
        "$match": {
            "sub_collection.field_I_want_to_match": "value"
        }
    }
])

-3
投票

您可以使用$ elemMatch使用$eq运算符

db.items.find({}, {
  "complist.b": 1,
  "list": { $elemMatch: { $eq: "a" } }
})

-9
投票

好吧,你可以在find的投影块上使用“array.field”。

 db.itens.find({},{"complist.b":1,list:{$elemMatch:{$in:["a"]}}})

做了我需要的。

© www.soinside.com 2019 - 2024. All rights reserved.