sql >> Databasteknik >  >> NoSQL >> MongoDB

Hitta en plats i en lagrad cirkel

Ännu mer optimal än originalet kan du nu använda $expr inom en $match skede efter den initiala $geoNear :

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

Egentligen lite mer optimalt än när det först skrevs. Nu kan vi bara $redact snarare än $project boolean och $match senare:

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 lagrat informationen precis som du ska, men det finns ett annat sätt att få resultaten än du tror.

Det du vill använda är en $geoNear och specifikt aggregationsramverket operatörens form. Så här gör du:

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å det formuläret tillåter att avståndet från den frågade punkten "projiceras" i resultaten, medan frågan också bara returnerar de närmaste dokumenten.

Sedan använder du en logisk jämförelse för att se om "distans"-värdet är mindre än "radie", alltså inom cirkeln.

Slutligen matchar du för att filtrera bort endast de resultat där det "inom" påståendet var sant.

Du kan lägga till andra alternativ till $geoNear som visas i dokumentationen. Jag skulle också starkt föreslå att din lagring också bör använda GeoJSON-formatet eftersom det sannolikt är mer kompatibelt med alla andra bibliotek du kan använda för att arbeta med de erhållna resultaten.



  1. Gör dynamiska frågor med Mongoose

  2. Fråga med strängdatumformat i mongodb

  3. Hur undviker man Redis-samtal i Lua-skriptbegränsningar?

  4. Mongoose - Öka ett värde inuti en array av objekt