mongodb-使用COLLSCAN而不是索引的$ lookup管道

时间:2019-01-26 21:52:34

标签: javascript mongodb

我正在尝试在$lookup管道上使用索引编制,但是它似乎没有按预期工作。

这是我的查询:

db.map_levels.explain().aggregate([
    {
        $lookup:
        {
            from: 
                "map_level_revisions",
            pipeline:
            [
                {
                    $match:
                    {
                        $expr:
                        {
                            $eq:
                            [
                                "$account_id",
                                ObjectId("5b66ca21d6b54f479bef62a4")
                            ]
                        }
                    }
                }
            ],
            as:
                "revisions"
        }
    },
])

这是解释:

{
    "stages" : [
        {
            "$cursor" : {
                "query" : {

                },
                "queryPlanner" : {
                    "plannerVersion" : 1,
                    "namespace" : "test-creator.map_levels",
                    "indexFilterSet" : false,
                    "parsedQuery" : {

                    },
                    "winningPlan" : {
                        "stage" : "COLLSCAN",
                        "direction" : "forward"
                    },
                    "rejectedPlans" : [ ]
                }
            }
        },
        {
            "$lookup" : {
                "from" : "map_level_revisions",
                "as" : "revisions",
                "let" : {

                },
                "pipeline" : [
                    {
                        "$match" : {
                            "$expr" : {
                                "$eq" : [
                                    "$account_id",
                                    ObjectId("5b66ca21d6b54f479bef62a4")
                                ]
                            }
                        }
                    }
                ]
            }
        }
    ],
    "ok" : 1
}

如何使用索引代替它?

仅需注意,查询确实会返回文档。

1 个答案:

答案 0 :(得分:0)

您的说明输出中的集合扫描是指map_levels值中指出的queryPlanner.namespace集合。 $lookup阶段将来自另一个集合的数据合并到当前管道中。由于您没有在$lookup之前指定任何查询阶段,因此将使用集合扫描来迭代map_levels集合。如果要加载整个集合而没有任何过滤或排序标准,则与对索引进行索引并提取文档相比,集合扫描的开销要小。

您可以通过在$match之前添加$lookup阶段来避免当前的集合扫描(假设您不想处理完整的map_levels集合)。

  

如何检查$lookup使用的索引?

不幸的是,查询说明输出没有(在MongoDB 4.0中)指示$lookup阶段的索引使用情况。为此,将使用您的查询pipeline作为顶级聚合查询来解释该问题。

MongoDB问题跟踪器中有一个相关的问题需要观察/投票:SERVER-22622: Improve $lookup explain to indicate query plan on the "from" collection