sql >> Databáze >  >> NoSQL >> MongoDB

Jak definovat kruh pro schéma mongo db?

Platí pro "geospatial query" „umístění“ musí být v zeměpisné délce a šířce řádu a nemůže obsahovat žádné jiné souřadnice.

Platné formáty jsou

 { 
     "location": [long,lat]
 }

Nebo

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

Nebo GeoJSON

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

Jiné pole, jako je „poloměr“, je „jiné pole“ a nemůže být součástí stejného pole.

Ideálně postupujte podle GeoJSON:

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

Což v definici schématu mongoose může být tak jednoduché jako:

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

Při práci s geoprostorovými daty na skutečných „globálních“ souřadnicích by váš index měl být "2dsphere" , který volitelně definujete ve schématu jako :

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

Protože v podporovaném GeoJSON neexistuje žádná skutečná podpora pro objekt „Circle“, doporučuje se ponechat jiné pole jako „poloměr“ a uložit „středový bod“.

„Velkou“ výhodou GeoJSON oproti jiným formátům „starších souřadnicových párů“ je to, že při vracení něčeho jako „vzdálenost“ od bodu přes geoNear nebo $geoNear pak je tato "vzdálenost" definována v "metrech" konzistentně. Takto byste také měli definovat jakoukoli hodnotu „poloměru“ ve vašem úložišti, abyste zůstali konzistentní s tímto výsledkem.

U ostatních formátů úložiště je pak výsledek vrácen v "radiánech", pro které pravděpodobně budete chtít převést a raději byste neukládali "poloměr" kruhu s tímto jako měřením.

Způsob, jakým se s tím vypořádáte, je, že vezmete v úvahu data v této podobě:

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

Pak použijete .aggregate() s $geoNear fázi a $redact filtrovat:

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

Nyní jsou hodnoty použité v příkladu dotazu pouze příkladem, ale jak je uvedeno u „skutečných“ souřadnic zeměpisné délky a šířky, atributy „vzdálenosti“ fungují tak, jak byly navrženy a v rámci tolerance „metrů“, jak bylo zmíněno dříve.

Jde o to, že $geoNear obě najdou "blízko" středového bodu "kruhu" bez ohledu na typ objektu. Nejen to, ale příkaz zde vytváří "projekci" jiného pole v dokumentu zde, jak je pojmenováno v "distanceField". To představuje vzdálenost od „středu“ kruhu v „metrech“.

Druhá fáze zde používá $redact protože je to něco jako $project a $match fáze potrubí v jednom. Na rozdíl od $match tento operátor může vyhodnotit "logickou" podmínku porovnáním polí přítomných v dokumentu. V tomto případě operace jako $$PRUNE odstraňte odpovídající dokument do podmínky "if" kde true a „odstranit“ jej z výsledků nebo jinak $$KEEP dokument, kde byla podmínka false .

Stručně řečeno, pokud je „vzdálenost“ „větší než“, pak „poloměr“ „kruhu“, pak objekt „leží mimo“ kruh a „neprotíná“. Jinak "to dělá".

To jsou základy „definování „kruhu“ pro geometrii v kolekci a „jeho použití“ k dosažení něčeho jako průsečík mezi „bodem“ nebo jiným typem objektu v rámci poloměru „kruhu“.




  1. Java&Mongo:získat objekt tam, kde existuje pole

  2. Jak provést výběr obrázku pomocí ejs a express?

  3. V Mongodb, Jak mohu indexovat pole (pole) v kolekcích pouze v sekundárním uzlu (sadě replik)

  4. Neočekávaný konec vstupu JSON s MongoDB Compass