Mongo $ near返回MultiPoint中任何点都在范围内的文档吗?

tar*_*mes 9 mongodb

在GeoJson对象上使用$near/ $geoNear/ $geoWithinMultiPoint,如果任何点在范围内,是否会返回文档,或者它们是否必须在范围内?

Bla*_*ven 11

"近"的案例

考虑的距离将始终来自存储的任何GeoJSON对象的"最近"点.对于Polygon或MultiPolygon以及对存储有效的所有GeoJSON对象也是如此.

考虑一下:

{
    "location": {
       "type": "MultiPoint",
       "coordinates": [
          [ -73.9580, 40.8003 ],
          [ -73.9498, 40.7968 ],
          [ -73.9737, 40.7648 ],
          [ -73.9814, 40.7681 ]
       ]
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我们使用聚合$geoNear 作为向我们显示距离给定位置的距离的方法:

db.geo.aggregate([
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [
               -73.97661209106445,
               40.774561857347244
            ]
        },
        "spherical": true,
        "distanceField": "distance"
    }}
])
Run Code Online (Sandbox Code Playgroud)

这告诉我们距离被认为是824米.

现在,如果您将每个"Point"视为自己的文档,而不是在集合中,并运行相同的查询过程:

{
        "location" : {
                "type" : "Point",
                "coordinates" : [
                        -73.9814,
                        40.7681
                ]
        },
        "distance" : 824.837276194968
}
{
        "location" : {
                "type" : "Point",
                "coordinates" : [
                        -73.9737,
                        40.7648
                ]
        },
        "distance" : 1114.0666715946495
}
{
        "location" : {
                "type" : "Point",
                "coordinates" : [
                        -73.958,
                        40.8003
                ]
        },
        "distance" : 3266.4720692258156
}
{
        "location" : {
                "type" : "Point",
                "coordinates" : [
                        -73.9498,
                        40.7968
                ]
        },
        "distance" : 3351.9091229713567
}
Run Code Online (Sandbox Code Playgroud)

然后你会看到每个点与原点的不同距离是查询,在前一种情况下,实际上只考虑整个对象的"最近".

因此,有证据表明,与$near/ $geoNear或考虑的距离始终只是与查询中使用的原点的最近点.

$ geoWithin的案例

$geoWithin然而,操作是不同的.考虑orginial"MultiPoint"文档,然后查询此查询:

db.geo.find({
    "location": {
        "$geoWithin": {
            "$geometry": {
                "type": "Polygon",
                "coordinates": [
                  [
                    [
                      -73.98382186889648,
                      40.75961056635002
                    ],
                    [
                      -74.00030136108398,
                      40.782751138401245
                    ],
                    [
                      -73.97317886352539,
                      40.78950978441435
                    ],
                    [
                      -73.95910263061523,
                      40.7720918760227
                    ],
                    [
                      -73.98382186889648,
                      40.75961056635002
                    ]
                  ]
                ]
            }
        }
    }
})
Run Code Online (Sandbox Code Playgroud)

这不会返回任何结果,也不会返回,因为Object的"并非所有"Point组件都位于查询中使用的tge Polygon的范围内.但如果您将每个点视为单个文档:

{
        "_id" : ObjectId("564d5efd9f28c6e0feabcef8"),
        "location" : {
                "type" : "Point",
                "coordinates" : [
                        -73.9737,
                        40.7648
                ]
        }
}
{
        "_id" : ObjectId("564d5efd9f28c6e0feabcef9"),
        "location" : {
                "type" : "Point",
                "coordinates" : [
                        -73.9814,
                        40.7681
                ]
        }
}
Run Code Online (Sandbox Code Playgroud)

然后可以看到两个点位于Polygon内部.但由于它们不是作为单独的文档存储而是作为"MutiPoint"的一部分存储,因此除非该对象的所有部分都包含在形状中,否则结果为false并且不返回文档.

对于所有GeoJSON对象来说也是如此,这些对象在某种表示中基本上包含"Point"的集合.