sql >> Database >  >> NoSQL >> MongoDB

Zoek een locatie binnen een opgeslagen cirkel

Nog beter dan het origineel, je kunt nu $expr binnen een $match fase na de initiële $geoNear :

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

Eigenlijk een beetje meer optimaal dan toen het voor het eerst werd geschreven. Nu kunnen we gewoon $redact in plaats van $project de boolean en $match later:

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

U heeft de informatie precies opgeslagen zoals u zou moeten, maar er is een andere benadering om de resultaten te krijgen dan u denkt.

Wat je wilt gebruiken is een $geoNear en specifiek het aggregatieraamwerk vorm van die exploitant. Dit is wat je doet:

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

Met die vorm kan de afstand vanaf het opgevraagde punt dus in de resultaten worden "geprojecteerd", terwijl de zoekopdracht ook alleen de dichtstbijzijnde documenten retourneert.

Dan gebruik je een logische vergelijking om te zien of de "afstand"-waarde kleiner is dan "radius", dus binnen de cirkel.

Ten slotte match je om alleen die resultaten te filteren waar die "binnen"-bewering waar was.

U kunt andere opties toevoegen aan $geoNear zoals weergegeven in de documentatie. Ik zou ook sterk aanbevelen dat je opslag ook het GeoJSON-formaat gebruikt, omdat dat waarschijnlijk beter compatibel is met alle andere bibliotheken die je zou kunnen gebruiken om aan de verkregen resultaten te werken.



  1. MongoDBObject wordt niet toegevoegd aan de binnenkant van een rrd foreach-lus casbah scala apache spark

  2. Mongoose:wat zijn de verschillen tussen Model.create en Collection.insert

  3. MongoDB-query's loggen met Spring Boot

  4. Mongodb haalt de 3-byte teller uit een ObjectId