简体   繁体   English

从不同文档的数组中获取多个对象MongoDb

[英]Get Multiple Objects From Array in different Documents MongoDb

My collection coll is 我的收藏馆是

/* 1 */
{
    "_id" : ObjectId("566121aa4b88d840eb7d1c50"),
    "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"),
    "array" : [ 
        {
            "id" : 1
        }, 
        {
            "id" : 2
        }, 
        {
            "id" : 3
        }, 
        {
            "id" : 4
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5661224a4b88d840eb7d1c51"),
    "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"),
    "array" : [ 
        {
            "id" : 1
        }, 
        {
            "id" : 7
        }, 
        {
            "id" : 3
        }, 
        {
            "id" : 5
        }
    ]
}

what i need is to pull objects in array 'array' where batchCourseId = ObjectId("566122ab94b792fbdf81bcf3") 我需要的是在array'array'中提取对象,其中batchCourseId = ObjectId(“ 566122ab94b792fbdf81bcf3”)

and 2<array.id<=5 2<array.id<=5

expected output is 预期输出为

/* 1 */
    {
        "_id" : ObjectId("566121aa4b88d840eb7d1c50"),
        "array" : [             
            {
                "id" : 3
            }, 
            {
                "id" : 4
            }
        ]
    }

/* 2 */
{
    "_id" : ObjectId("5661224a4b88d840eb7d1c51"),
    "array" : [            
        {
            "id" : 3
        }, 
        {
            "id" : 5
        }
    ]
}

already tried 已经尝试过

db.coll.find({"batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3")},
    { array: { $elemMatch: { id: { $gt: 2,$lte: 5} } } })

the output is like 输出就像

/* 1 */
{
    "_id" : ObjectId("566121aa4b88d840eb7d1c50"),
    "array" : [ 
        {
            "id" : 3
        }
    ]
}

/* 2 */
{
    "_id" : ObjectId("5661224a4b88d840eb7d1c51"),
    "array" : [ 
        {
            "id" : 3
        }
    ]
}

close but only the first matching object in array is in result 关闭,但仅结果数组中的第一个匹配对象

FYI this only a sample set of data the original data is more complex and big in count 仅供参考,这只是样本数据集,原始数据更复杂且数量更多

so pls let me know the best practice to do this, performance is also important 因此,请让我知道执行此操作的最佳做​​法,性能也很重要

thanks in advance 提前致谢

You can use aggregation for achieving the same. 您可以使用聚合来实现相同目的。 A sample is shown below: 示例如下所示:

db.coll.aggregate(
  {$match: {"batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3")}},
  {$unwind: '$array'},
  {$match: {'array.id': { $gt: 2,$lte: 5}}},
  {$group: {_id: '$_id', array: {$push : '$array'}}}
)

Result: 结果:

{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "array" : [ { "id" : 3 }, { "id" : 5 } ] }
{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "array" : [ { "id" : 3 }, { "id" : 4 } ] }

In MongoDB aggregation $unwind creates Cartesian_product problem so in large data set is good way to avoid $unwind . 在MongoDB中,聚合$unwind会产生Cartesian_product问题,因此在大数据集中避免$unwind是一个好方法。

Let's check with your example if you use $unwind in aggregation then result looks like this 让我们检查您的示例,如果您在aggregation使用$unwind ,则结果如下所示

db.collectionName.aggregate([
    { "$match": { "batchCourseId": ObjectId("566122ab94b792fbdf81bcf3") }}, 
    { "$unwind": "$array" }
])

so result of above query is : 所以上述查询的结果是:

{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 1 } }
{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 2 } }
{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 3 } }
{ "_id" : ObjectId("566121aa4b88d840eb7d1c50"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 4 } }
{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 1 } }
{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 7 } }
{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 3 } }
{ "_id" : ObjectId("5661224a4b88d840eb7d1c51"), "batchCourseId" : ObjectId("566122ab94b792fbdf81bcf3"), "array" : { "id" : 5 } }

this create multiple documents and in large documents in collections it slow the performance and increase processing time. 这会创建多个文档,而在集合中的大文档中会降低性能并增加处理时间。

Instead of $unwind use $map in aggregation with aggregation-set operator and the query is as below : 代替$ unwind使用$ map聚合集运算符聚合 ,查询如下:

db.collection.aggregate([{
  "$match": {
    "batchCourseId": ObjectId("566122ab94b792fbdf81bcf3")
  }
}, {
  "$project": {
    "array": {
      "$setDifference": [{
          "$map": {
            "input": "$array",
            "as": "el",
            "in": {
              "$cond": {
                "if": {
                  "$and": [{
                    "$gt": ["$$el.id", 2]
                  }, {
                    "$lte": ["$$el.id", 5]
                  }]
                },
                "then": "$$el",
                "else": false
              }
            }
          }
        },
        [false]
      ]
    }
  }
}])

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM