MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Trova una posizione all'interno di una cerchia memorizzata

Ancora più ottimale dell'originale, ora puoi utilizzare $expr all'interno di un $match fase dopo il $geoNear :

db.collection.aggregate([
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ 23.027573, 72.50675800000001 ],
        },
        "distanceField": "distance"
    }},
    { "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])

In realtà un po' più ottimale di quando è stato scritto per la prima volta. Ora possiamo solo $redact anziché $project il booleano e $match dopo:

db.collection.aggregate([
    // Match documents "near" the queried point
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ 23.027573, 72.50675800000001 ],
        },
        "distanceField": "distance"
    }},

    // Calculate if distance is within radius and remove if not
    { "$redact": {
        "$cond": {
            "if": { "$lte": [ "$distance", "$radius" ] },
            "then": "$$KEEP",
            "else": "$$PRUNE"
        }
    }}
])

Hai memorizzato le informazioni esattamente come dovresti, ma c'è un approccio diverso per ottenere i risultati da quello che pensi.

Quello che vuoi usare è un $geoNear e in particolare il framework di aggregazione forma di tale operatore. Ecco cosa fai:

db.collection.aggregate([
    // Match documents "near" the queried point
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [ 23.027573, 72.50675800000001 ],
        },
        "distanceField": "distance"
    }},

    // Calculate if distance is within radius
    { "$project": {
        "location": 1,
        "radius": 1,
        "distance": 1,
        "within": { "$lte": [ "$distance", "$radius" ] }
    }},

    // Match only documents within the radius
    { "$match": { "within": true } }
])

Quindi quel modulo consente di "proiettare" nei risultati la distanza dal punto interrogato, mentre la query restituirà anche solo i documenti più vicini.

Quindi usi un confronto logico per vedere se il valore di "distanza" è inferiore a "raggio", quindi all'interno del cerchio.

Infine, abbini per filtrare solo i risultati in cui l'asserzione "dentro" era vera.

Puoi aggiungere altre opzioni a $geoNear come mostrato nella documentazione. Suggerirei inoltre caldamente che il tuo spazio di archiviazione utilizzi anche il formato GeoJSON in quanto è probabile che sia più compatibile con qualsiasi altra libreria tu possa utilizzare per lavorare sui risultati ottenuti.