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

MongoDB Geospacial Query Spheres overlappende enkeltpunkt

Det ville være bedre, hvis du kunne bruge et GeoJSON-objekt til at repræsentere placeringen, men i øjeblikket er understøttede typer er faktisk begrænsede så en "Cirkel"-type, som ville være ideel, understøttes ikke.

Det nærmeste, du kan gøre, er en "Polygon", der tilnærmer en cirkel, men dette er sandsynligvis lidt for meget arbejde at konstruere kun til dette forespørgselsformål. Den anden har det godt med at gøre dette og derefter anvende $geoIntersects er, at resultaterne ikke bliver "sorteret" efter afstanden fra forespørgselspunktet. Det ser ud til at være det modsatte af formålet med at finde den "nærmeste pizza" til oprindelsesstedet.

Heldigvis er der en $geoNear operation tilføjet til aggregeringsrammen fra MongoDB 2.4 og nyere. Det gode her er, at det tillader "projektion" af et afstandsfelt i resultaterne. Dette giver dig derefter mulighed for at udføre den logiske filtrering på serveren til de punkter, der er "inden for radius"-begrænsningen til afstanden fra oprindelsespunktet. Det tillader også sortering på serveren.

Men du bliver stadig nødt til at ændre dit skema for at understøtte indekset

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

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

Og for aggregeringsforespørgslen:

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

Dybest set siger dette,

Der er andre muligheder, du kan videregive til $geoNear for at forfine resultatet, samt returnere mere end standard 100 resultater, hvis det kræves og dybest set videregive andre muligheder for at forespørge, såsom en "type" eller "navn" eller hvilken som helst anden information, du har på dokumentet.




  1. Skub element til array i mongoose

  2. PyMongo Opdater dokument med flere poster

  3. Er det muligt at bruge forespørgselsprojektion på den samme samling, som har en $elemMatch-projektion?

  4. Hadoop InputFormat &typer af InputFormat i MapReduce