我在“ timeofcollection”上有一个索引。存在一个问题,即在显示索引扫描时,正在扫描使用同一字段显示的集合的一个查询。这些是我在下面发布的聚合管道中的“ $ match”步骤。有人可以帮我解释什么是问题以及如何处理吗?
如果我在管道中的$ match步骤中进行了跟踪,则其评估为索引扫描
{
"timeofcollection":{$gte:ISODate("2020-09-24T00:00:00.000+0000"),$lt:ISODate('2020-09-25T00:00:00.000+0000')}
}
如果我在管道中执行以下步骤,则其评估为集合扫描
{
$match: {
"$expr": {
"$and": [{
"$gte": [
"$_id.dt",
{
"$subtract": [{
"$toDate": {
"$dateToString": {
"date": "$$NOW",
"format": "%Y-%m-%dT00:00:00.000+0000"
}
}
},
86400000
]
}
],
},
{
"$lt": [
"$_id.dt",
{
"$toDate": {
"$dateToString": {
"date": "$$NOW",
"format": "%Y-%m-%dT00:00:00.000+0000"
}
}
}
]
}
]
}
}
}
基本上,我要达到的目的是提取过去一天的记录。效果很好,但是涉及到我无法进行的集合扫描。
有帮助吗?
答案 0 :(得分:1)
查询计划者仅在使用$expr运算符时才使用索引进行相等性比较。
它也将仅在表达式的值对于查询恒定时才使用索引。由于$$NOW
变量在查询开始执行之前没有绑定,并且每次执行都会具有不同的值,因此查询计划者将不会使用使用该变量的查询的索引。
答案 1 :(得分:0)
这可能不是一个完整的答案,但是我发现上述汇总存在一个明显的问题,就是由于某种原因,您似乎将日期转换为文本,而只是将日期再次转换为日期。通常,如果您的过滤器包含timeofcollection
的 function ,则timeofcollection
上的索引可能不可用。试试这个版本:
$match: {
"$expr": {
"$and": [
{
"$gte": [
"$_id.dt",
{
"$subtract": [ "$$NOW", 86400000 ]
}
],
},
{
"$lt": [
"$_id.dt", "$$NOW",
]
}
]
}
}
请注意,我在这里假设上面片段中的dt
是timeofcollection
的别名,它是在较早的位置定义的。
关键是在函数中使用timeofcollection
可能会使索引无法使用。上面的版本可能会解决此问题。