Javascript 如何在Mongo聚合查询中使用现有字段作为$match的修饰符
我的数据结构类似于:Javascript 如何在Mongo聚合查询中使用现有字段作为$match的修饰符,javascript,mongodb,date,mongodb-query,aggregation-framework,Javascript,Mongodb,Date,Mongodb Query,Aggregation Framework,我的数据结构类似于: { _id: ObjectId("5a7f534b337e8d2b97ff2ff"), cutoff: 3, schedules: [ { starts: ISODate('2020-04-22T00:00:00.000Z'), ends: ISODate('2020-04-22T00:00:00.000Z'), repeats: 'never' }, { starts: ISODate('
{
_id: ObjectId("5a7f534b337e8d2b97ff2ff"),
cutoff: 3,
schedules: [
{
starts: ISODate('2020-04-22T00:00:00.000Z'),
ends: ISODate('2020-04-22T00:00:00.000Z'),
repeats: 'never'
},
{
starts: ISODate('2020-04-30T00:00:00.000Z'),
ends: ISODate('2020-06-30T00:00:00.000Z'),
repeats: 'monthly'
}
]
}
我想建立一个按重叠日期范围搜索的查询,即:
const from=新日期(2020年4月25日)
施工日期=新日期(2020年5月5日)
等待数据存储
.collection('事物')
.合计([
{
$match:{
'schedules.start':{$lte:to},
'schedules.ends':{$gte:from}
}
}
])
问题是我需要考虑到搜索的截止点,因此我发现了$expr
,并尝试将其应用于我的查询:
$match:{
'schedules.starts':{$lte:to.toDate()},
'schedules.ends':{$expr:{$gte:{$add:[from.toDate(),{$multiply:['$cutoff',24,60,60000]}
}
我一直在尝试使用$expr
使其在查询中正常工作,但我要么收到错误信息,要么没有得到任何结果。我不确定如何继续
我曾考虑在匹配之前使用
$project
或$addFields
来简化,但我从手册中了解到,这将导致我的多键索引停止工作。您的$match
条件对我来说不是很清楚。通常,您可以使用现有字段:
var from = new Date(2020, 04, 25)
var to = new Date(2020, 05, 5)
db.collection.aggregate([
{ $addFields: { from: from } },
{ $addFields: { to: to } },
{ $addFields: { ends: { $toDate: { $add: [from.getTime(), { $multiply: ['$cutoff', 24, 60, 60, 1000] }] } } } }
])
返回
{
"_id" : ObjectId("5e5530e922139e9b31aa786c"),
"cutoff" : 3.0,
"schedules" : [
{
"starts" : ISODate("2020-04-22T02:00:00.000+0200"),
"ends" : ISODate("2020-04-22T02:00:00.000+0200"),
"repeats" : "never"
},
{
"starts" : ISODate("2020-04-30T02:00:00.000+0200"),
"ends" : ISODate("2020-06-30T02:00:00.000+0200"),
"repeats" : "monthly"
}
],
"from" : ISODate("2020-05-25T00:00:00.000+0200"),
"to" : ISODate("2020-06-05T00:00:00.000+0200"),
"ends" : ISODate("2020-05-28T00:00:00.000+0200")
}
为了在$match
中使用它
db.collection.aggregate([
{
$match: {
$expr: {
$gte: [
"$schedules.ends",
{ $toDate: { $add: [from.getTime(), { $multiply: ['$cutoff', 24, 60, 60, 1000] }] } }
]
}
}
}
])
我认为您必须使用的聚合版本,因为您将gte运算符与
$expr
一起使用。您好,Wernfried-感谢您的帮助,但是我相信$addFields是一个投影运算符,因此这将意味着我的查询不再使用索引,对吗?当然,第一个查询返回时不会使用任何索引反正都是文件。