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

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

问题描述

我有一个像

    {
        "_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.

这里的主要区别在于查询"完全按照它的意图执行并匹配满足您条件的文档".您可以尝试使用 positional $ 投影参数中的运算符,但其中的规则是它只会匹配与查询条件匹配的第一个"数组元素.

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$setDifference:

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 当您只查询数组中单个键的值时不需要."Dot notation" 在仅访问单个密钥时是首选和推荐的的阵列.$elemMatch 仅当数组element"中文档中的多个"键需要匹配查询条件时才需要.

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天全站免登陆