数组所有字段的MongoDB条件 [英] MongoDB condition for all fields of array

查看:107
本文介绍了数组所有字段的MongoDB条件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在mongodb中是否可以查询字段为数组且其所有元素都满足条件的查找文档?

Is it possible in mongodb do a query for find documents where the field is an array and all its elements satisfy a condition?

例如:

[
  {
    "_id": ObjectId("53d63d0f5c7ff000227cd372"),
    "works": [
      {
        "code": "A001",
        "items": [
          {
            "_id": "534664b081362062015d1b77",
            "qty": 6
          },
          {
            "_id": "534ba71f394835a7e51dd938",
            "qty": 5
          }
        ],
        "name": "Cambiar bombilla",
        "price": 100,
        "Date": "2014-07-30T09:43:17.593Z",
        "TechnicianId": "538efd918163b19307c59e8e",
        "percent": 2,
        "_id": ObjectId("53d63d0f5c7ff002207cd372")
      },
      {
        "code": "A001",
        "name": "Cambiar bombilla",
        "price": 100,
        "type": "Bombillas",
        "TechnicianId": "538efd918163b19307c59e8e",
        "date": "2014-07-31T13:36:34.019Z",
        "orderId": "53d63d0f5c7ff000007cd372",
        "_id": ObjectId("53da466568c26f8a72b50fcb"),
        "percent": 66
      }
    ]
  },
  {
    "_id": ObjectId("53d63d0f5c7ff000007cd372"),
    "works": [
      {
        "code": "A001",
        "items": [
          {
            "_id": "534664b081362062015d1b77",
            "qty": 6
          },
          {
            "_id": "534ba71f394835a7e51dd938",
            "qty": 5
          }
        ],
        "name": "Cambiar bombilla",
        "price": 100,
        "Date": "2014-07-30T09:43:17.593Z",
        "TechnicianId": "538efd918163b19307c59e8e",
        "percent": 2,
        "_id": ObjectId("53d63d0f5c7ff002207cd372")
      },
      {
        "code": "A001",
        "name": "Cambiar bombilla",
        "price": 100,
        "type": "Bombillas",
        "TechnicianId": "538efd918163b19307c59e8e",
        "date": "2014-07-31T13:36:34.019Z",
        "orderId": "53d63d0f5c7ff000007cd372",
        "_id": ObjectId("53da466568c26f8a72b50fcb"),

      }
    ]
  }
]

我需要找到像第一个文档一样的文档,因为在Works字段中,他的子文档具有百分比,但是在第二个文档中,第二位置的Works数组没有百分比.

I need to find the documents like first document because in works field his subdocuments have percent, but in the second document, works array at second position doesnt have percent.

推荐答案

以简单的方式测试数组的每个元素中是否存在字段并不容易.可以测试购买键的值需要花费更多的精力.

It's not easy to test for the existence of a field in every element of an array in a simple way. Values can be tested for buy keys take a bit more work.

该方法是通过聚合框架完成的,以便处理数组元素的条件,然后匹配结果.

The approach is done with the aggregation framework in order to process conditions for the array elements and then match the result.

首先,在MongoDB 2.6及更高版本中,您将获得一些帮助:

Firstly with MongoDB 2.6 and greater you get some helpers:

db.collection.aggregate([
    // Filter out to match only possible documents
    { "$match": {
        "works.percent": { "$exists": true }
    }},

    // Find matching through projection
    { "$project": {
        "works": 1,
        "matched": {
            "$allElementsTrue": {
                "$map": {
                    "input": "$works",
                    "as": "el",
                    "in": { "$ifNull": [ "$$el.percent", false ] }
                }
            }
        }
    }},

    // Filter to return only the true matches
    { "$match": { "matched": true } }

])

或者使用 $unwind 在以前的版本中:

Or a bit longer and possibly slower with $unwind in prior versions:

db.collection.aggregate([
    // Filter out to match only possible documents
    { "$match": {
        "works.percent": { "$exists": true }
    }},

    // Unwind the array
    { "$unwind": "$works" },

    // Find matching by conditionally evaluating and grouping
    { "$group": {
        "_id": "$_id",
        "works": { "$push": "$works" },
        "matched": { 
            "$min": {
                "$cond": [
                    { "$ifNull": [ "$works.percent", false ] },
                    true,
                    false
                ]
            }
        }
    }}

    // Filter to return only the true matches
    { "$match": { "matched": true } }

])

无论哪种情况,它都是 $ifNull 运算符,其等效于 $exists 运算符,代表聚合运算符.在$exists的查询"表单测试是否存在字段的情况下,$ifNull评估该字段存在的地方,然后返回值,否则返回替代参数.

In either case, it is the $ifNull operator that works as the equivalent of the $exists operator in a aggregation operator sense. Where the "query" form for $exists tests whether a field is present, $ifNull evaluates that where the field is present then the value is returned, otherwise the alternate argument is returned instead.

但是基本上需要对数组进行处理,以查看是否所有元素都存在必填字段,因为对此没有标准的查询等效项.

But the arrays basically need to be processed to see if all elements have the required field present as there is no standard query equivalent for this.

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

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