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

Find en placering i en gemt cirkel

Endnu mere optimal end originalen kan du nu bruge $expr inden for en $match trin efter den indledende $geoNear :

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

Faktisk lidt mere optimalt, end da det først blev skrevet. Nu kan vi bare $redact i stedet for $project den boolske og $match senere:

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"
        }
    }}
])

Du har gemt oplysningerne præcis, som du skal, men der er en anden tilgang til at få resultaterne, end du tror.

Det du vil bruge er en $geoNear og specifikt aggregeringsramme den pågældende operatørs form. Her er hvad du gør:

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 } }
])

Så den form gør det muligt at "projicere" afstanden fra det forespurgte punkt i resultaterne, mens forespørgslen også kun returnerer de nærmeste dokumenter.

Så bruger du en logisk sammenligning til at se, om "afstand"-værdien er mindre end "radius", derfor inden for cirklen.

Til sidst matcher du for kun at filtrere de resultater fra, hvor den "indenfor" påstand var sand.

Du kan tilføje andre muligheder til $geoNear som vist i dokumentationen. Jeg vil også kraftigt foreslå, at dit lager også skal bruge GeoJSON-formatet, da det sandsynligvis vil være mere kompatibelt med de andre biblioteker, du måtte bruge til at arbejde på de opnåede resultater.



  1. MongoDB $pop

  2. Hvilke MongoDB-typer bevares ikke af mongoimport/mongoexport?

  3. Gem delmængde af MongoDB-samling til en anden samling

  4. Hvordan får du adgang til en MongoDB-database fra to Openshift-apps?