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

Hvordan definerer man en cirkel for et mongo db-skema?

At være gyldig for en "geospatial forespørgsel" "placeringen" skal være i længdegrad, breddegrad rækkefølge og kan ikke indeholde andre koordinater.

Gyldige formater er

 { 
     "location": [long,lat]
 }

Eller

 {
    "location": { "lng": long, "lat": lat }
 }

Eller GeoJSON

 {
     "location": {
         "type": "Point",
         "coordinates": [long,lat]
     }
 }

Et andet felt såsom "radius" er "et andet felt" og kan ikke være en del af det samme array.

Følg helst GeoJSON:

 {
     "location": {
         "type": "Point",
         "coordinates": [long,lat]
     },
     "radius": radius
 }

Hvilket i mongoose-skemadefinition kan være så simpelt som:

var geoSchema = new Schema({
    "location": {
        "type": String,
        "coordinates": []
    },
    "radius": Number
});

Når du håndterer geospatiale data ved rigtige "globe"-koordinater, skal dit indeks være "2dsphere" , som du valgfrit definerer på skemaet som :

geoSchema.index({ "location": "2dsphere" })

Da der ikke er nogen egentlig understøttelse af et "Circle"-objekt i understøttet GeoJSON, anbefales det at beholde et andet felt som "radius" og gemme "midtpunktet".

Den "store" fordel med GeoJSON i forhold til de andre "legacy koordinatpar"-formater er, at når man returnerer noget som en "afstand" fra et punkt via geoNear eller $geoNear så er denne "afstand" konsekvent defineret i "meter". Det er også sådan, du skal definere enhver "radius"-værdi i dit lager for at forblive i overensstemmelse med det resultat.

Med de andre lagringsformater returneres resultatet i "radianer", som du sandsynligvis vil konvertere til og helst ikke vil gemme en "radius" af en cirkel med det som en måling.

Måden du håndterer dette på er, i betragtning af data i denne form:

{
    "locationtype": "circle",
    "location": {
        "type": "Point",
        "coordinates": [1,1]
    },
    "radius": 4
}

Så bruger du .aggregate() med en $geoNear scene og en $redact for at filtrere:

db.collection.aggregate([
    // Find points or objects "near" and project the distance
    { "$geoNear": {
        "near": {
            "type": "Point",
            "coordinates": [2,2]
        },
        "distanceField": "distance",
        "query": { "locationType": "circle" }
    }},
    // Logically filter anything outside of the radius
    { "$redact": {
        "$cond": {
            "if": { "$gt": [ "$distance", "$radius" ] },
            "then": "$$PRUNE",
            "else": "$$KEEP"
        }
    }}
])

Nu er de anvendte værdier i forespørgselseksemplet kun et eksempel, men som nævnt med "rigtige" længde- og breddegradskoordinater fungerer "distance"-attributterne som designet og inden for "meter"-tolerancen som nævnt tidligere.

Punkterne her er, at $geoNear vil både finde "nær" på "cirklen" midterste poiny, uanset hvilken objekttype. Ikke kun det, men kommandoen her producerer en "projektion" af et andet felt i dokumentet her som navngivet i "distanceField". Dette repræsenterer afstanden fra cirklen "center" i "meter".

Det andet trin her bruger $redact da det ligner et $projekt og $match pipeline fase i én. I modsætning til $match denne operatør kan evaluere en "logisk" tilstand ved at sammenligne felter i dokumentet. I dette tilfælde, operationer som $$ BESKÆR fjern det matchede dokument til "hvis"-tilstanden, hvor true og "fjern" det fra resultater eller på anden måde $$KEEP dokumentet, hvor betingelsen var false .

I en "nøddeskal", hvis "afstand" er "større end" så "radius" af "cirklen", så "ligger objektet uden for" cirklen og "skærer ikke". Ellers "gør det".

Så det er det grundlæggende i "at definere en 'cirkel' for geometri i en samling og "bruge den" til at opnå noget i retning af skæringspunktet mellem et "punkt" eller en anden type objekt inden for "cirklen"-radius.




  1. Hvordan håndterer Redis Streams at bruge al tilgængelig hukommelse?

  2. gemme ip-intervaller i Redis

  3. MongoDB opdaterer et dokument, når det allerede eksisterer med ReactiveMongo

  4. Problemer med at sende JSON-data (med nodeanmodning) til Express-serveren til lagring i MongoDB