查找查询 - 在 $elemMatch 之后按数组大小过滤

Find Query - Filter by array size after $elemMatch

是否可以在 $elemMatch 过滤后根据数组的大小 return 记录?

例如,如果我在一个集合中有很多记录,如下所示:

[
{
    contents: [
        {
            name: "yorkie",
        },
        {
            name: "dairy milk",
        },
        {
            name: "yorkie",
        },
    ]
},
// ...
]

我想找到所有 contents 字段包含 2 个数组项且 name 字段等于 "yorkie" 的记录,我该怎么做?澄清一下,该数组可以包含其他项,但只要这些数组项中的 2 个具有匹配的 field:value.

就满足条件。

我知道我可以使用 $elemMatch(或 contents.name)到 return 记录,其中数组包含至少一个与该名称匹配的项目,我知道我也可以使用 $size 根据记录字段中数组项的确切数量进行过滤。有什么办法可以把它们结合起来吗?

不在 find 查询中,但可以通过聚合完成:

db.test.aggregate([
    { "$match" : { "contents.name" : "yorkie" } },
    { "$unwind" : "$contents" },
    { "$match" : { "contents.name" : "yorkie" } },
    { "$group" : { "_id" : "$_id", "sz" : { "$sum" : 1 } } },    // use $first to include other fields
    { "$match" : { "sz" : { "$gte" : 2 } } }
])

我翻译了

the criteria is met so long as 2 of those array items have the matching field:value

表示如果至少有 2 个数组项具有 name 中的匹配值,则满足条件。

我知道这个帖子很旧,但今天你可以使用 find

db.test.find({
"$expr": { 
    "$gt": [ 
        { 
            "$reduce": {
                "input": "$contents",
                "initialValue": 0,
                "in": {"$cond": {"if": {"$eq": ["$$this.name", 'yorkie']}, then: { "$add": ["$$value", 1] } , "else": "$$value" } }
            }
        }, 1]
}

}

reduce 会在这里发挥作用,return 符合条件的对象数量