sql >> Database >  >> NoSQL >> MongoDB

Hoe definieer je een cirkel voor een mongo db-schema?

Geldig zijn voor een "geospatial query" de "locatie" moet in lengtegraad, breedtegraad . zijn bestelling en mag geen andere coördinaten bevatten.

Geldige formaten zijn

 { 
     "location": [long,lat]
 }

Of

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

Of GeoJSON

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

Een ander veld zoals "radius" is "another field" en kan niet deel uitmaken van dezelfde array.

Volg idealiter GeoJSON:

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

Wat in de definitie van een mangoestschema zo simpel kan zijn als:

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

Als je te maken hebt met geospatiale gegevens op echte "globe"-coördinaten, moet je index "2dsphere" , die u optioneel in het schema definieert als :

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

Aangezien er geen daadwerkelijke ondersteuning is voor een "Circle"-object in ondersteunde GeoJSON, wordt aanbevolen om een ​​ander veld als "radius" te behouden en het "middelpunt" op te slaan.

Het "grote" voordeel met GeoJSON ten opzichte van de andere "oude coördinatenparen"-formaten is dat bij het retourneren van iets als een "afstand" vanaf een punt via geoNear of $geoNear dan wordt die "afstand" consequent gedefinieerd in "meters". Dit is ook hoe u elke "radius" -waarde in uw opslag moet definiëren om consistent te blijven met dat resultaat.

Bij de andere opslagformaten wordt het resultaat geretourneerd in "radialen", waarvoor u waarschijnlijk wilt converteren en liever geen "radius" van een cirkel met die als maat opslaat.

De manier waarop u hiermee omgaat is, rekening houdend met gegevens in deze vorm:

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

Dan gebruik je .aggregate() met een $geoNear stage en een $redact om te filteren:

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 zijn de waarden die in het queryvoorbeeld worden gebruikt slechts een voorbeeld, maar zoals vermeld met "echte" lengte- en breedtegraadcoördinaten werken de "afstand"-attributen zoals ontworpen en binnen de "meters"-tolerantie zoals eerder vermeld.

De punten hier zijn dat $geoNear zullen beide "dichtbij" bij het middelpunt van de "cirkel" vinden, ongeacht het objecttype. Niet alleen dat, maar de opdracht hier produceert een "projectie" van een ander veld in het document hier zoals genoemd in "distanceField". Dit vertegenwoordigt de afstand van de cirkel "middelpunt" in "meters".

De tweede fase hier gebruikt $redact aangezien het een soort $project en $match pijplijntrap in één. In tegenstelling tot $match deze operator kan een "logische" voorwaarde evalueren door velden in het document te vergelijken. In dit geval zijn bewerkingen zoals $$ snoeien verwijder het overeenkomende document naar de "if"-voorwaarde waarbij true en "verwijder" het uit resultaten of anderszins $$KEEP het document waar de voorwaarde false was .

In een "notendop", als "afstand" "groter dan" is, dan "straal" van de "cirkel", dan "ligt" het object "buiten" van de cirkel en "kruist" het niet. Anders "doet het dat wel".

Dat is dus de basis van het "definiëren van een 'cirkel' voor geometrie in een verzameling en 'gebruiken' om zoiets te bereiken als de kruising tussen een 'punt' of een ander type object binnen de 'cirkel'-straal.




  1. MongoDB-relaties:insluiten of verwijzen?

  2. Spring MongoRepository is aan het updaten of upsert in plaats van in te voegen

  3. Voeg een soort rijnummer toe aan een mongodb-aggregaatopdracht / pijplijn

  4. Hoe maak je een staartbare cursor in de MongoDB-shell?