MongoDB elemmatch数组中的多个元素 [英] MongoDB elemmatch multiple elements in array

查看:62
本文介绍了MongoDB elemmatch数组中的多个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个mongodb文档,例如

I have an mongodb document like

    {
        "_id" : ObjectId("54e66b2da7b5f3a92e09dc6c"),
        "SomeMetric" : [ 
            {
                //some object
            }
            {
                //some object
            } 
         ],
        "FilterMetric" : [ 
            {
                "min" : "0.00",
                "max" : "16.83",
                "avg" : "0.00",
                "class" : "s1"
            }, 
            {
                "min" : "0.00",
                "max" : "16.83",
                "avg" : "0.00",
                "class" : "s2"
            }, 
            {
                "min" : "0.00",
                "max" : "16.83",
                "avg" : "0.00",
                "class" : "s1"
            }, 
            {
                "min" : "0.00",
                "max" : "16.83",
                "avg" : "0.00",
                "class" : "s2"
            } 
        ]
    }

通常,它包含许多这样的嵌套数组.我只想投影一个指标,仅使用具有搜索条件的数组. 我有查询

Typically it contains many nested arrays like this. I want to project one metric alone, with only the arrays that have my search criteria. I have the query

db.sample.find(
{"filtermetric.class" : "s2"},{"filtermetric" : { $elemMatch : {class: "s2"}}}
)

这仅给我数组中的第一个对象.没有返回第二个类为s2的对象.

This gives me only the first object in the array. The second object with class : s2 is not returned.

如果我尝试

    db.sample.find(
   {"filtermetric" : { $elemMatch : {class: "s2"}}}
    )

它给了我数组中的所有4个对象.

It give me all the 4 objects in the array.

在这种情况下,如何获取所有符合条件的对象?

How do I get all the objects that match a criteria in such a case?

推荐答案

您不能以任何基本.find()查询形式返回匹配条件的数组的多个元素.要匹配多个元素,您需要使用 .aggregate() 方法代替.

You cannot return multiple elements of an array matching your criteria in any form of a basic .find() query. To match more than one element you need to use the .aggregate() method instead.

此处的主要区别在于,查询"完全按照预期进行,并匹配满足您条件的文档".您可以尝试在投影中使用位置$ 运算符参数,但是有一个规则,那就是它只会匹配与查询条件匹配的第一个"数组元素.

The main difference here is that the "query" does exactly what it is intended to do and matches "documents" that meet your conditions. You can try to use the positional $ operator within a projection argument, but the rules there is that it will only match the "first" array element that matches the query conditions.

为了过滤"多个数组元素,请按照下列步骤操作:

In order to "filter" for multiple array elements, proceed as follows:

db.sample.aggregate([
    // Filter possible documents
    { "$match": { "filtermetric.class": "s2" } },

    // Unwind the array to denormalize
    { "$unwind": "$filtermetric" },

    // Match specific array elements
    { "$match": { "filtermetric.class": "s2" } },

    // Group back to array form
    { "$group": {
        "_id": "$_id",
        "filtermetric": { "$push": "$filtermetric" }
    }}
])

在2.6或更高版本的MongoDB现代版本中,您可以使用 $redact :

In modern versions of MongoDB that are version 2.6 or greater you can do this with $redact :

db.sample.aggregate([
    // Filter possible documents
    { "$match": { "filtermetric.class": "s2" } },

    // Redact the entries that do not match
    { "$redact": {
        "$cond": [
            { "$eq": [ { "$ifNull": [ "$class", "s2" ] }, "s2" ] },
            "$$DESCEND",
            "$$PRUNE"
        ]
    }}
])

这可能是您最有效的选择,但是它是递归的,因此请首先考虑您的文档结构,因为相同的命名字段在任何级别都不能与其他条件一起存在.

That is probably your most efficient option, but it is recursive so consider your document structure first as the same named field cannot exist with any other condition at any level.

此技术可能更安全,但仅在数组结果真正唯一"的情况下才有用,这种技术具有 $map

Possibly safer but only useful where the results in the array are "truly unique" is this technique with $map and $setDifference:

db.sample.aggregate([
    { "$project": {
        "filtermetric": { "$setDifference": [
            { "$map": [
                "input": "$filtermetric",
                "as": "el",
                "in": {"$cond": [
                    { "$eq": [ "$$el.class", "s2" ] },
                    "$$el",
                    false
                ]}
            ]},
            [false]
        ]}
    }}
])

还请注意,在 $group 中, > $project 您需要 的运营管道阶段来指定该阶段要在结果文档中返回的所有字段.

Also noting that in both the $group and $project operational pipeline stages you need to specify all of the fields you intend to return in your result documents from that stage.

最后一点是 $elemMatch 当您仅查询数组中单个键的值时,不需要.仅在访问单个密钥时,首选并推荐点符号" 的数组. $elemMatch仅在数组元素"内的文档中的多个"键需要匹配查询条件时才需要.

The final note is that $elemMatch is not required when you are only querying the value of a single key within an array. "Dot notation" is preferred and recommended when only accessing a single key of the array. $elemMatch should only be needed when "multiple" keys in the document within the array "element" need to match a query condition.

这篇关于MongoDB elemmatch数组中的多个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆