Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MongoDB geoNear Aggregation - Order of Operations

I have a simple MongoDo Aggregation query:

{
    "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [
                -73.982,
                40.7685
            ]
        },
        "spherical": "true",
        "distanceField": "d",
        "limit": 100000,
        "maxDistance": 8046.7,
        "query": {
            "ipv": 1
        }
    }
},
{
    "$sort": {
        "created_at": -1
    }
},
{
    "$limit": 5
}

My simple question is along the lines of query order of operations. Does the query scan ALL documents for a matching coords, then from that data set, matches ipv: 1, then sorted by created_at, then limit 5?

If so - this isn't happening. I have a to place a "limit" field, or it will only scan back 100 of the last records, match the geo coords, then do the order of operations.

Is there a way to have MongoDB scan ALL records for the matching GPS Coords, then perform the matching?

like image 329
gregavola Avatar asked Dec 14 '25 12:12

gregavola


1 Answers

Here's how $geoNear works: It gets a cursor to documents whose coordinates satisfy the maxDistance requirement. It then iterates over the cursor and for each document checks if it matches the query requirement. If it doesn't, it skips it and moves to the next document. It does this until it finds limit-many documents or the end of the cursor. Note that this is the limit argument to the $geoNear command, not the $limit operation specified later in the aggregation pipeline.

The default limit is 100, so if you don't specify limit you are getting the first 100 documents that match query and whose coordinates satisfy maxDistance, sorting those 100 documents by created_at, and then taking the first 5. When you specify limit:100000, you are getting the first 100000 documents that match query and whose coordinates satisfy maxDistance, sorting those 100000 documents by created_at, and then taking the first 5.

If you are trying to get the 5 nearest documents to your Point, and then sort those 5 documents by created_at, you should set the $geoNear limit to 5 and remove the $limit operation from the pipeline altogether. If you want to scan ALL documents for matching coordinates, sort the resulting documents by created_at, and then get the first 5, you should set the $geoNear limit to a value larger than the size of the collection, and leave the rest as you have it. Hope that helps.

like image 52
jribnik Avatar answered Dec 18 '25 03:12

jribnik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!