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

时间:2015-04-13 22:11:23

标签: arrays mongodb filter database

在$ elemMatch对其进行过滤后,是否可以根据数组的大小返回记录?

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

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

我想查找所有记录,其contents字段包含2个数组项,其name字段等于" yorkie",我该怎么做?为了澄清,该数组可以包含其他项,但只要其中2个数组项具有匹配的字段:value即可满足条件。

我知道我可以使用$elemMatch(或contents.name)来返回数组中至少包含一个与该名称匹配的项目的记录,而且我知道我也可以使用$size根据记录字段中的确切数组项进行过滤。有没有办法可以将两者结合起来?

2 个答案:

答案 0 :(得分:2)

不在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 } } }
])

我解释了

  

只要其中2个数组项具有匹配的字段:value

,就符合条件

表示如果至少2个数组项在name中具有匹配值,则符合条件。

答案 1 :(得分:0)

我知道这个线程很旧,但是今天您可以使用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将在此处解决问题,并将返回符合条件的对象数量