Mongo数据库集合扫描或索引扫描

问题描述

我在“ 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"
                                        }
                                    }
                                }
                            ]
                        }
                    ]
                }
            }
        }

基本上,我要达到的目的是提取过去一天的记录。效果很好,但是涉及到我无法进行的集合扫描。

有帮助吗?

解决方法

查询计划者仅在使用$expr运算符时才使用索引进行相等性比较。

它也将仅在表达式的值对于查询恒定时才使用索引。由于$$NOW变量在查询开始执行之前没有绑定,并且每次执行都会具有不同的值,因此查询计划者将不会使用使用该变量的查询的索引。

,

这可能不是一个完整的答案,但是我发现上述汇总存在一个明显的问题,就是由于某种原因,您似乎将日期转换为文本,而只是将日期再次转换为日期。通常,如果您的过滤器包含timeofcollection function ,则timeofcollection上的索引可能不可用。试试这个版本:

$match: {
            "$expr": {
                "$and": [
                    {
                        "$gte": [
                            "$_id.dt",{
                                "$subtract": [ "$$NOW",86400000 ]
                            }
                        ],},{
                        "$lt": [
                            "$_id.dt","$$NOW",]
                    }
                ]
            }
        }

请注意,我在这里假设上面片段中的dttimeofcollection的别名,它是在较早的位置定义的。

关键是在函数中使用timeofcollection可能会使索引无法使用。上面的版本可能会解决此问题。