获取日期范围内的数组元素 [英] Get elements of an array in date range

查看:112
本文介绍了获取日期范围内的数组元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的MongoDB集合中的示例文档:

This is an example document in my MongoDB collection:

 var user: [{
            "_id" : ObjectId("5391b11a3c0a9ac01300006d"),
            "injurydata" : {                
                "injuryinformation" : [ 
                    {
                        "status" : "current",
                        "updateddate" : ISODate("2014-06-06T12:16:20.306Z"),
                        "updatedby" : "",
                        "dateofinjury" : ISODate("2014-06-27T18:30:00.000Z"),                          
                        "_id" : ObjectId("5391b11a3c0a9ac01300006f")
                    }                   
                ]
            }
         },
         {
            "_id" : ObjectId("5391b11a3c0a9ac01300006d"),
            "injurydata" : {                
                "injuryinformation" : [ 
                    {
                        "status" : "current",
                        "updateddate" : ISODate("2014-06-06T12:16:20.306Z"),                           
                        "dateofinjury" : ISODate("2014-06-28T18:30:00.000Z"),                            
                        "_id" : ObjectId("5391b11a3c0a9ac01300006f")
                    }                   
                ]
            }
         },
         {
            "_id" : ObjectId("5391b11a3c0a9ac01300006d"),
            "injurydata" : {                
                "injuryinformation" : [ 
                    {
                        "status" : "current",                            
                        "dateofinjury" : ISODate("2014-08-10T18:30:00.000Z"),                            
                        "_id" : ObjectId("5391b11a3c0a9ac01300006f")
                    }                   
                ]
            }
         }]

在此文档中,我只需要injuryinformation在2014-06-28和2014-06-30之间的那些injuryinformation数组元素,所以我只会得到前两个元素.

From this document, I want only those injuryinformation array elements for which dateofinJURY is between 2014-06-28 and 2014-06-30, so I will only get first two elements.

我尝试了此查询,但仍然可以得到整个数组

I tried this query but I still get the whole array

db.user.find(
{
    $and: 
    [
        {"injury.injurydata.injuryinformation.dateofinjury": 
        {"$gte": ISODate("2014-05-21T08:00:00Z") , "$lt": ISODate("2014-06- 03T08:00:00Z")}},       
        {"_id":ObjectId("538d9a1dd173e5202a00005d")}
    ],

})

推荐答案

_id匹配在您的语句中相当明确,因此不仅会否定对数组条目进行范围"匹配的需要,而且还会否定 $and 的任何用法实际上在MongoDB查询中是隐式的. $and 条件本质上是除非您实际上是在同一字段上要求多个条件,否则不需要默认".但是你不在这里.

Well the _id match is fairly explicit in your statement so not only will that negate the need for the "range" match on array entries but it also negates any usage of $and which is actually implicit in MongoDB queries. The $and condition is essentially the "default" and is not required unless you are actually asking for multiple conditions on te same field. But here you are not.

匹配多个数组元素需要使用 .aggregate() 作为.find()可用的投影",不能向您显示来自数组的一个匹配条目:

Matching multiple array elements you need to use .aggregate() as the "projection" available to .find() cannot show you more than one matching entry from an array:

db.collection.aggregate([

    // Match the document but not actually the array
    { "$match": {
        "injury.injurydata.injuryinformation.dateofinjury": {
            "$gte": ISODate("2014-05-21T08:00:00Z"), 
            "$lt": ISODate("2014-06-03T08:00:00Z")
        },       
        "_id": ObjectId("538d9a1dd173e5202a00005d")
    }},

    // Unwind the arrays to "de-normalize" as documents
    { "$unwind": "$injury" },
    { "$unwind": "$injury.injurydata" }, 
    { "$unwind": "$injury.injurydata.injuryinformation" },

    // Match the actual array elements
    { "$match": {
        "injury.injurydata.injuryinformation.dateofinjury": {
            "$gte": ISODate("2014-05-21T08:00:00Z"), 
            "$lt": ISODate("2014-06-03T08:00:00Z")
        }
    }},

    // Group those back to and array, maybe?
    { "$group": {
        "_id": "$_id",
        "information": {
            "$push": "$injury.injrydata.injuryinformation"
        }
    }}
])

或使用 $map 进行过滤" 在MongoDB 2.6和更高版本中,看起来更长但更快:

Or "filtering" with $map under MongoDB 2.6 and greater, looks longer but faster:

db.collection.aggregate([

    // Match the document but not actually the array
    { "$match": {
        "injury.injurydata.injuryinformation.dateofinjury": {
            "$gte": ISODate("2014-05-21T08:00:00Z"), 
            "$lt": ISODate("2014-06-03T08:00:00Z")
        },       
        "_id": ObjectId("538d9a1dd173e5202a00005d")
    }},

    // Unwind the arrays to "de-normalize" as documents
    { "$unwind": "$injury" },
    { "$unwind": "$injury.injurydata" }, 

    // Project with the "$map" filter
    { "$project": {
        "information": {
            "$setDifference": [
                "$map": {
                    "input": "$injury.injurydata.injuryinformation",
                    "as": "el",
                    "in": {
                        "$cond": [
                            {
                                "$and": [
                                    { 
                                        "$gte": [ 
                                            "$$el.dateofinjury",
                                            ISODate("2014-05-21T08:00:00Z")
                                        ]
                                    },
                                    {
                                        "$lt": [
                                            "$$el.dateofinjury",
                                            ISODate("2014-06-03T08:00:00Z")
                                        ]
                                    }
                                ]
                            }
                        ],
                        false
                    }
                },
                [false]
            ]
        }
    }}

])

所使用的 $和条件存在另一种形式,可用于 $match 操作之外的聚合框架表达式,这些表达式等效于.find()查询

The $and condition used in there is a different form that is available to aggregation framework expressions outside of $match operations that are equivalent to .find() queries.

不确定伤害"顶线从哪里来,因为它在您的样本中没有显示,但是我认为您确实有.

Not sure where the "injury" top line comes from there as it is not represented in your sample, but I assume you actually have it.

这篇关于获取日期范围内的数组元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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