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“.