In Mongo what is the difference between $near and $nearSphere?

后端 未结 1 2094
既然无缘
既然无缘 2021-02-18 21:23

I read the docs and its not very clear what the difference is between the two.

The only difference I found is that in nearSphere it explicitly says that Mongo calculates

1条回答
  •  忘了有多久
    2021-02-18 21:58

    The keyword is sphere to differentiate between $near and $nearSphere.

    As you are aware, $nearSphere is stated to calculate distance using spherical geometry. This is related to the Earth map projection (distortion). Where MongoDB 2d indexes is based on Cartesian and MongoDB 2dsphere indexes is based on Geodesic.

    Enough theory, let's use some examples. Let's say we have two documents as below:

    db.map.insert({ "_id": "Westfield London", "location": [ -0.22157, 51.507176 ] });
    db.map.insert({ "_id": "Green Lanes Shopping Centre", "location": [ -0.098092, 51.576198 ] });
    

    The manual for both operators specify that we can use:

    • 2dsphere index for location data defined as GeoJSON points
    • 2d index for location data defined as legacy coordinate pairs

    Index: 2dsphere , Query: GeoJSON

    db.map.createIndex({"location": "2dsphere"});
    
    db.map.find({"location":{"$nearSphere":{"$geometry":{"type":"Point", "coordinates":[ -0.127748, 51.507333 ] }}}});
    
    db.map.find({"location":{"$near":{"$geometry":{"type":"Point", "coordinates":[ -0.127748, 51.507333 ]}}}});
    

    In this case, both queries will return the same result, because the index is stored in 2dsphere.

    Result:

    [ /* $nearSphere */
        {"_id" : "Westfield London"},
        {"_id" : "Green Lanes Shopping Centre"}
    ]
    [ /* $near */
        {"_id" : "Westfield London"},
        {"_id" : "Green Lanes Shopping Centre"}
    ]
    

    Index: 2d , Query: Legacy Coordinates

    db.map.createIndex({"location": "2d"});
    
    db.map.find({"location":{"$nearSphere":[ -0.127748, 51.507333 ]}});
    
    db.map.find({"location":{"$near":[ -0.127748, 51.507333 ]}});
    

    This is where the distinction happens, the result for $nearSphere is calculated spherically despite the index, while $near is calculated in flat projection.

    Result:

    [ /* $nearSphere */
        {"_id" : "Westfield London"},
        {"_id" : "Green Lanes Shopping Centre"}
    ]
    [ /* $near */
        {"_id" : "Green Lanes Shopping Centre"},
        {"_id" : "Westfield London"}
    ]
    

    See gist: JS test script of the above example. This was tested using MongoDB v3.4.4.

    Also see Geospatial Indexes and Queries.

    0 讨论(0)
提交回复
热议问题