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

时间:2020-09-27 05:41:24

标签: mongodb match aggregation

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

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

有帮助吗?

2 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

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

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

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