sql >> Database >  >> NoSQL >> MongoDB

MongoDB Geospacial Query Spheres die één punt overlappen

Nou, het zou leuker zijn als je een GeoJSON-object zou kunnen gebruiken om de locatie weer te geven, maar vanaf heden de ondersteunde typen zijn eigenlijk beperkt dus een type "Cirkel" dat ideaal zou zijn, wordt niet ondersteund.

Het beste wat je zou kunnen doen is een "polygoon" die een cirkel benadert, maar dit is waarschijnlijk een beetje te veel werk om alleen voor dit query-doel te construeren. De andere moet dit doen en vervolgens $geoIntersects is dat de resultaten niet worden "gesorteerd" op de afstand vanaf het vraagpunt. Dat lijkt het tegenovergestelde te zijn van het doel om de "dichtstbijzijnde pizza" te vinden op het punt van herkomst.

Gelukkig is er een $geoNear bewerking toegevoegd aan het aggregatieraamwerk vanaf MongoDB 2.4 en hoger. Het goede hier is dat het de "projectie" van een afstandsveld in de resultaten mogelijk maakt. Dit stelt u vervolgens in staat om de logische filtering op de server uit te voeren op die punten die "binnen de straal" beperkt zijn tot de afstand vanaf het punt van oorsprong. Het maakt het ook mogelijk om op de server te sorteren.

Maar je zult nog steeds je schema moeten wijzigen om de index te ondersteunen

db.places.insert({
    "name": "Pizza Hut",
    "location": { 
        "type": "Point",
        "coordinates": [
            151.00211262702942,
            -33.81696995135973
        ]
    },
    "radius": 20
})

db.places.ensureIndex({ "location": "2dsphere" })

En voor de aggregatiequery:

db.places.aggregate([

    // Query and project distance
    { "$geoNear": {
        "near": { 
            "type": "Point",
            "coordinates": [ 
                150.92094898223877,
                -33.77654333272719
            ]
        },
        "distanceField": "distance",
        "distanceMultiplier": 0.001,
        "maxDistance": 100000,
        "spherical": true
    }},

    // Calculate if distance is within delivery sphere
    { "$project": {
         "name": 1,
         "location": 1,
         "radius": 1,
         "distance": 1,
         "within": { "$gt": [ "$radius", "$distance" ] }
    }},

    // Filter any false results
    { "$match": { "within": true } },

    // Sort by shortest distance from origin
    { "$sort": { "distance": -1 } }
])

Dit zegt eigenlijk:

Er zijn andere opties die u kunt doorgeven aan $geoNear om het resultaat te verfijnen, en indien nodig meer dan de standaard 100 resultaten te retourneren en in feite andere opties door te geven om te zoeken, zoals een "type" of "naam" of welke andere informatie u ook op het document heeft.




  1. Een op GUID gebaseerde Shard-sleutel programmatisch vooraf splitsen met MongoDB

  2. Hoe serialiseer je waardetypes met MongoDB C# serializer?

  3. Hoe test je een methode die verbinding maakt met mongo, zonder daadwerkelijk verbinding te maken met mongo?

  4. Mongoose breidt standaardvalidatie uit