我在我的 mongoDB 中有一个集合,它存储提供给客户的服务以及他们的电子邮件地址,如下所示
{
"_id" : ObjectId("56a84627f8fd4a136c0e944a"),
"Vehicle" : "Honda",
"ServiceSelected" : "FULL SERVICE",
"FullName" : "xyz",
"Email" : "xyz@xyz.com",
"BookingTime" : ISODate("2015-12-27T06:00:00.000Z")
},
{
"_id" : ObjectId("56a84627f8fd4a136c0e944b"),
"Vehicle" : "AUDI",
"ServiceSelected" : "FLAT TYRE",
"FullName" : "abc",
"Email" : "abc@abc.com",
"BookingTime" : ISODate("2015-12-26T06:00:00.000Z")
},
{
"_id" : ObjectId("56a84627f8fd4a136c0e944c"),
"Vehicle" : "BMW",
"ServiceSelected" : "OTHERS",
"FullName" : "def",
"Email" : "def@def.com",
"BookingTime" : ISODate("2015-12-25T06:00:00.000Z")
},
{
"_id" : ObjectId("56a84627f8fd4a136c0e944d"),
"Vehicle" : "BMW",
"ServiceSelected" : "OTHERS",
"FullName" : "def",
"Email" : "def@def.com",
"BookingTime" : ISODate("2015-12-30T06:00:00.000Z")
},
{
"_id" : ObjectId("56a84627f8fd4a136c0e944a"),
"Vehicle" : "Honda",
"ServiceSelected" : "FULL SERVICE",
"FullName" : "xyz",
"Email" : "xyz@xyz.com",
"BookingTime" : ISODate("2016-01-27T06:00:00.000Z")
}
我想从上面的集合中获取至少间隔 30 天的所有文档,即从上面的集合中“电子邮件”:“xyz@xyz.com”应该返回但不是“电子邮件”:“def@def.com”,因为在 5 天内接受了第二次服务。
我知道设计存在缺陷,可以在从应用程序插入记录时设置一个额外的标志,但我需要为现有记录获取数据。
最佳答案
您需要使用 $min
和 $max
分别返回 $group
中“BookingTime”的最小值和最大值的运算符阶段。管道的最后阶段是 $redact
使用 $divide
使用简单的“日期”数学的阶段和 $subtract
算术运算符。返回第一个“服务”和最后一个“服务”之间的天数大于 30 的文档
db.collection.aggregate( [
{ "$group": {
"_id": "$Email",
"date1": { "$min": "$BookingTime" },
"date2": { "$max": "$BookingTime" }
}},
{ "$redact": {
"$cond": [
{ "$gte": [
{ "$divide": [
{ "$subtract": [ "$date2", "$date1" ] },
1000 * 60 * 60 * 24
]},
30
]},
"$$KEEP",
"$$PRUNE"
]
}}
])
哪个返回:
{
"_id" : "xyz@xyz.com",
"date1" : ISODate("2015-12-27T06:00:00Z"),
"date2" : ISODate("2016-01-27T06:00:00Z")
}
另一种方法是使用 $cond
$project
阶段中的运算符以避免集合扫描。
db.collection.aggregate( [
{ "$group": {
"_id": "$Email",
"date1": { "$min": "$BookingTime" },
"date2": { "$max": "$BookingTime" },
"count": { "$sum": 1 }
}},
{ "$match": { "count": { "$gte": 2 } } },
{ "$project": {
"emails": {
"$cond": [
{ "$gte": [
{ "$divide": [
{ "$subtract": [ "$date2", "$date1" ] },
1000 * 60 * 60 * 24
]},
30
] },
"$_id",
false
]
}
}},
{ "$match": { "emails": { "$ne": false } } }
])
关于多个文档之间的MongoDB dateDiff,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35055073/