MongoDB $center 的地理空间索引

MongoDB geospatial index on $center

集合架构

{
    "_id" : ObjectId("5d3562bf1b48d90ea4b06a74"),
    "name" : "19",
    "location" : {
        "type" : "Point",
        "coordinates" : [
            50.0480208,
            30.5239127
        ]
    }
}

索引

> db.places.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_",
        "ns" : "test.places"
    },
    {
        "v" : 2,
        "key" : {
            "location" : "2dsphere"
        },
        "name" : "location_2dsphere",
        "ns" : "test.places",
        "2dsphereIndexVersion" : 3
    }

集合中存储了 200 万个文档。

首先我运行这样查询。

db.places.find({ location: {$geoWithin: { $center: [[60.0478308, 40.5237227], 10] } }})

但是需要2秒。所以我通过 explain() 检查查询。

> db.places.find({ location: {$geoWithin: { $center: [[60.0478308, 40.5237227], 10] } }}).explain('executionStats')
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "test.places",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "location" : {
                "$geoWithin" : {
                    "$center" : [
                        [
                            60.0478308,
                            40.5237227
                        ],
                        10
                    ]
                }
            }
        },
        "winningPlan" : {
            "stage" : "COLLSCAN",
            "filter" : {
                "location" : {
                    "$geoWithin" : {
                        "$center" : [
                            [
                                60.0478308,
                                40.5237227
                            ],
                            10
                        ]
                    }
                }
            },
            "direction" : "forward"
        },
        "rejectedPlans" : [ ]
    },
    "executionStats" : {
        "executionSuccess" : true,
        "nReturned" : 1414213,
        "executionTimeMillis" : 2093,
        "totalKeysExamined" : 0,
        "totalDocsExamined" : 2000000,
        "executionStages" : {
            "stage" : "COLLSCAN",
            "filter" : {
                "location" : {
                    "$geoWithin" : {
                        "$center" : [
                            [
                                60.0478308,
                                40.5237227
                            ],
                            10
                        ]
                    }
                }
            },
            "nReturned" : 1414213,
            "executionTimeMillisEstimate" : 1893,
            "works" : 2000002,
            "advanced" : 1414213,
            "needTime" : 585788,
            "needYield" : 0,
            "saveState" : 15681,
            "restoreState" : 15681,
            "isEOF" : 1,
            "invalidates" : 0,
            "direction" : "forward",
            "docsExamined" : 2000000
        }
    },
    "serverInfo" : {
        "host" : "Johnui-iMac",
        "port" : 27017,
        "version" : "4.0.3",
        "gitVersion" : "7ea530946fa7880364d88c8d8b6026bbc9ffa48c"
    },
    "ok" : 1
}

你知道查询阶段是COLLSCAN

我想知道,我已经为 location 个字段创建了索引,但它似乎不起作用。

所以我创建了更多索引。

        "v" : 2,
        "key" : {
            "location.coordinates" : 1
        },
        "name" : "location.coordinates_1",
        "ns" : "test.places"
    },
    {
        "v" : 2,
        "key" : {
            "location" : 1
        },
        "name" : "location_1",
        "ns" : "test.places"
    }

但是也不行。

我的索引配置有问题吗?

您似乎已经在您的位置创建了一个 2dsphere 索引,但是 $centre 上的 MongoDB docs 指定:

Only the 2d geospatial index supports $center.

因此,我建议您在位置字段上创建一个 2d 索引,然后将使用该索引执行扫描