zap*_*984 4 mongodb mongodb-query aggregation-framework
如果我在mongoDB中保存了以下架构中的文档:
{
createdDate: Date,
lastUpdate: Date
}
Run Code Online (Sandbox Code Playgroud)
是否可以查询创建和上次更新之间的时间段是否大于一天的文档?
最佳选择是使用$redact聚合管道阶段:
db.collection.aggregate([
{ "$redact": {
"$cond": {
"if": {
"$gt": [
{ "$subtract": [ "$lastUpdate", "$createdDate" ] },
1000 * 60 * 60 * 24
]
},
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
Run Code Online (Sandbox Code Playgroud)
因此,您正在查看差值的毫秒值,该值大于一天的毫秒值.在$subtract做数学的区别,当两个日期相减返回以毫秒为单位的差异.
在$redact操作者取逻辑表达式为"如果",且其中该条件是true它要执行的操作在"然后",这是到$$KEEP该文档.如果是,false那么文档将从结果中删除$$PRUNE.
请注意,由于这是一个逻辑条件而不是设定值或值范围,因此不使用"索引".
由于聚合管道中的操作是本机编码的,因此这是您可以获得的最快的执行语句.
替代是JavaScript评估$where.这需要一个JavaScript函数表达式,需要类似地返回一个true或false值.在shell中你可以像这样简写:
db.collection.find(function() {
return ( this.lastUpdate.valueOf() - this.createdDate.valueOf() )
> ( 1000 * 60 * 60 * 24 );
})
Run Code Online (Sandbox Code Playgroud)
同样的事情,除了JavaScript评估需要解释并且运行速度比.aggregate()等效的慢得多.出于同样的原因,这种类型的表达式不能使用索引来优化性能.
为获得最佳结果,请将差异存储在文档中.然后你可以直接在该属性上查询,当然你也可以索引它.
从 开始Mongo 5,这是新$dateDiff聚合运算符的完美用例:
// { created: ISODate("2021-12-05T13:20"), lastUpdate: ISODate("2021-12-06T05:00") }
// { created: ISODate("2021-12-04T09:20"), lastUpdate: ISODate("2021-12-05T18:00") }
db.collection.aggregate([
{ $match: {
$expr: {
$gt: [
{ $dateDiff: { startDate: "$created", endDate: "$lastUpdate", unit: "hour" } },
24
]
}
}}
])
// { created: ISODate("2021-12-04T09:20"), lastUpdate: ISODate("2021-12-05T18:00") }
Run Code Online (Sandbox Code Playgroud)
created这会计算和日期之间相差的小时数lastUpdate,并检查是否大于24 hours。
| 归档时间: |
|
| 查看次数: |
7349 次 |
| 最近记录: |