MongoDB聚合查询,在子文档中包含日期月份

时间:2018-01-16 10:35:37

标签: mongodb mongodb-query

这是我的收藏记录

[
    {
        "username" : "av4617",
        "subscriptions" : [ 
            {
                "sub_id" : "5a56fd399dd78e33948c9b8e",
                "activation_date" : ISODate("2018-01-01T00:00:00.000Z")
            }, 
            {
                "sub_id" : "5a56fd399dd78e33948c9b8e",
                "activation_date" : ISODate("2018-02-01T00:00:00.000Z")
            }, 
            {
                "sub_id" : "5a56fd399dd78e33948c9b8e",
                "activation_date" : ISODate("2018-01-01T00:00:00.000Z")
            }
        ]
    },
    {
        "username" : "av4611",
        "subscriptions" : [ 
            {
                "sub_id" : "5a56fd399dd78e33948c9b8e",
                "activation_date" : ISODate("2018-01-01T00:00:00.000Z")
            }
        ]
    }
]

我想要的是具有两个日期范围内的用户订阅详情的记录。我已经尝试了

db.gyms.aggregate([
 {'$unwind': '$subscriptions'},   
   { "$match": { "subscriptions.activation_date": { "$exists": true } } },    
    {        
     "$redact": {      
        "$cond": [           
             { "$eq": [{ "$month": "$subscriptions.activation_date" }, 1] }, "$$KEEP","$$PRUNE"           
                 ]} } 
        ]).pretty()

但它返回

{
        "username" : "av4617",
        "subscriptions" : {
                "sub_id" : "5a56fd399dd78e33948c9b8e",
                "activation_date" : ISODate("2018-01-01T00:00:00Z")
        }
}
{
        "username" : "av4617",
        "subscriptions" : {
                "sub_id" : "5a56fd399dd78e33948c9b8e",
                "activation_date" : ISODate("2018-01-01T00:00:00Z")
        }
}
{
        "username" : "av4611",
        "subscriptions" : {
                "sub_id" : "5a56fd399dd78e33948c9b8e",
                "activation_date" : ISODate("2018-01-01T00:00:00Z")
        }
}

当我尝试使用$$ DESCEND代替$$ KEEP时,它适用于其他数据类型..但在上面的查询中,由于日期数据类型,它给出了错误。

assert: command failed: {
        "ok" : 0,
        "errmsg" : "can't convert from BSON type missing to Date",
        "code" : 16006,
        "codeName" : "Location16006"
}

我想要的是一份文件中的次大陆......

[{
            "username" : "av4617",
            "subscriptions" : {
                    "sub_id" : "5a56fd399dd78e33948c9b8e",
                    "activation_date" : ISODate("2018-01-01T00:00:00Z")
            },
            {
                    "sub_id" : "5a56fd399dd78e33948c9b8e",
                    "activation_date" : ISODate("2018-01-01T00:00:00Z")
            }
},
{
        "username" : "av4611",
        "subscriptions" : {
                "sub_id" : "5a56fd399dd78e33948c9b8e",
                "activation_date" : ISODate("2018-01-01T00:00:00Z")
        }
}]

1 个答案:

答案 0 :(得分:0)

您的问题是由"activation_date"字段中缺少正确日期值的文档引起的,如下所示:

{
    "username" : "av4611",
    "subscriptions" : {
        "sub_id" : "5a56fd399dd78e33948c9b8e",
        "activation_date": null
    }
}

$exists运算符也将返回true,因此不会过滤掉它们。您可以这样检查字段的$type

{ "$match": { "subscriptions.activation_date": { $type: "date" } } }

请注意,您的查询不是以过于有效的方式编写的,因此您可能希望使用@ Veeram的建议。