How to find 25 uniformly distributed documents in a geo bounding box?

198 views Asked by At

I have a collection of documents with a location field. I need to find documents within a bounding box, and limit the number of result documents (let's say 25). But I also need these 25 docs were uniformly distributed all over the bounding box (not just any 25 random docs). Is there any way I can achieve this with MongoDB?

1

There are 1 answers

11
AudioBubble On

With a bit of math and thinking then you can get the "nearest" items to the centre of the box. It takes a few operations from the initial query with some help from the aggregation framework.

Lets assume a box of origin (0,0) and a max edge of (4,4), which makes the centre (2,2). Then you would issue the following:

db.collection.aggregate([
    // Find results near to the centre of the box
    { "$geoNear": {
        "near": {
            "type": "Point",
            "geometry": [2,2]
        },
        "maxDistance": 4,        // limit a bit outside the boundary
        "distanceField": "dist"  // Projected field with distance
    }},

    // Filter out results outside the box
    { "$match": {
        "$geoWithin": {
            "box": [
                [0,0],
                [4,4]
            ]
        }
    }},

    // Sort by distance
    { "$sort": { "dist": 1 } }

    // Limit the results
    { "$limit": 25 }
])

So that's the basic principle. Take note to actually consider what co-ordinate system you are using and whether the data is stored in legacy or GeoJSON format as this affects the distance projected as documented.

But essentially $geoNear finds the features that fall "close to" the centre of the box you later describe. Most importantly it "projects" a field representing the "distance" from the point queried. Then the $geoWithin matches those items that actually fall inside the box.

All that remains is to $sort to the nearest entries first, then $limit the total results to a maximum of 25 from the nearest entry first.