sql >> Databasteknik >  >> NoSQL >> MongoDB

Hur definierar man en cirkel för ett mongo db-schema?

För att vara giltig för en "geospatial query" "platsen" måste vara i longitud, latitud ordning och kan inte innehålla några andra koordinater.

Giltiga format är

 { 
     "location": [long,lat]
 }

Eller

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

Eller GeoJSON

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

Ett annat fält som "radie" är "ett annat fält" och kan inte vara en del av samma array.

Följ helst GeoJSON:

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

Vilket i mongoose-schemadefinition kan vara så enkelt som:

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

När du hanterar geospatiala data på verkliga "globe"-koordinater bör ditt index vara "2dsphere" , som du valfritt definierar i schemat som :

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

Eftersom det inte finns något faktiskt stöd för ett "Circle"-objekt i GeoJSON som stöds, rekommenderas att behålla ett annat fält som "radie" och lagra "mittpunkten".

Den "stora" fördelen med GeoJSON jämfört med de andra "legacy koordinatpar"-formaten är att när man returnerar något som ett "avstånd" från en punkt via geoNear eller $geoNear då definieras det "avståndet" i "meter" konsekvent. Det är också så du bör definiera alla "radie"-värden i din lagring för att förbli konsekvent med det resultatet.

Med de andra lagringsformaten returneras resultatet i "radianer", som du förmodligen vill konvertera och föredrar att inte lagra en "radie" av en cirkel med det som ett mått.

Sättet du hanterar detta är, med tanke på data i denna form:

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

Sedan använder du .aggregate() med en $geoNear steg och en $redact för att filtrera:

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 är värdena som används i frågeexemplet bara ett exempel, men som nämnts med "riktiga" longitud- och latitudkoordinater fungerar "distance"-attributen som designade och inom "meters"-toleransen som nämnts tidigare.

Poängen här är att $geoNear kommer båda att hitta "nära" "cirkeln" mittpunkten oavsett vilken objekttyp. Inte bara det utan kommandot här producerar en "projektion" av ett annat fält i dokumentet här som heter i "distanceField". Detta representerar avståndet från cirkeln "centrum" i "meter".

Det andra steget här använder $redact eftersom det är ungefär som ett $projekt och $match rörledningssteg i ett. Till skillnad från $match denna operatör kan utvärdera ett "logiskt" tillstånd genom att jämföra fält som finns i dokumentet. I det här fallet, operationer som $$ PRUNE ta bort det matchade dokumentet till "om"-villkoret där true och "ta bort" det från resultaten eller på annat sätt $$KEEP dokumentet där villkoret var false .

I ett "nötskal", om "avstånd" är "större än" då "radie" för "cirkeln" så "ligger objektet utanför" cirkeln och "korsar sig inte". Annars "gör det".

Så det är grunderna för att "definiera en "cirkel" för geometri i en samling och "använda den" för att uppnå något som liknar skärningspunkten mellan en "Punkt" eller annan typ av objekt inom "cirkelns" radie.




  1. MongoDB infogar float när man försöker infoga heltal

  2. Var är AccountKey för CosmosDB i Azure Portal

  3. Uppgradering av äldre mongo-databas efter oavsiktlig mongoversionsuppgradering

  4. Spring Boot kan inte uppdatera sharded-samlingen på azure cosmos db(MongoDb)