Да бъде валиден за "геопространствена заявка" "местоположението" трябва да е в дължина, ширина ред и не може да съдържа други координати.
Валидни формати са
{
"location": [long,lat]
}
Или
{
"location": { "lng": long, "lat": lat }
}
Или GeoJSON
{
"location": {
"type": "Point",
"coordinates": [long,lat]
}
}
Друго поле като „радиус“ е „друго поле“ и не може да бъде част от същия масив.
В идеалния случай следвайте GeoJSON:
{
"location": {
"type": "Point",
"coordinates": [long,lat]
},
"radius": radius
}
Което в дефиницията на схема на mongoose може да бъде толкова просто, колкото:
var geoSchema = new Schema({
"location": {
"type": String,
"coordinates": []
},
"radius": Number
});
Когато работите с геопространствени данни при реални координати на "глобус", вашият индекс трябва да бъде "2dsphere" , което по желание дефинирате в схемата като :
geoSchema.index({ "location": "2dsphere" })
Тъй като няма реална поддръжка за обект „Кръг“ в поддържания GeoJSON, тогава се препоръчва запазване на друго поле като „радиус“ и съхраняване на „централната точка“.
„Голямото“ предимство с GeoJSON пред другите формати на „наследени координатни двойки“ е, че при връщане на нещо като „разстояние“ от точка чрез geoNear
или $geoNear
тогава това "разстояние" се дефинира последователно в "метри". Също така трябва да дефинирате всяка стойност на „радиус“ във вашето хранилище, за да останете в съответствие с този резултат.
С другите формати за съхранение тогава резултатът се връща в "радиани", за които вероятно искате да конвертирате и бихте предпочели да не съхранявате "радиус" на кръг с това като измерване.
Начинът, по който се справяте с това, е, като имате предвид данните в тази форма:
{
"locationtype": "circle",
"location": {
"type": "Point",
"coordinates": [1,1]
},
"radius": 4
}
След това използвате .aggregate()
с $geoNear
етап и $redact
за филтриране:
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"
}
}}
])
Сега стойностите, използвани в примера за заявка, са само пример, но както е посочено с „реални“ координати на дължина и ширина, атрибутите „разстояние“ работят както са проектирани и в рамките на толеранса „метри“, както беше споменато по-рано.
Точките тук са, че $geoNear
и двете ще намерят "близо" до центъра на "кръга" без значение какъв е типът на обекта. Не само това, но командата тук създава "проекция" на друго поле в документа тук, както е посочено в "distanceField". Това представлява разстоянието от "центъра" на кръга в "метри".
Вторият етап тук използва $redact
тъй като е нещо като $projectкод>
и $match
етап на тръбопровод в едно. За разлика от $match
този оператор може да оцени "логично" условие чрез сравняване на полета, присъстващи в документа. В този случай операции като $$ ПОДРЕЖЕТЕ
премахнете съответстващия документ към условието "if", където true
и го „премахнете“ от резултатите или по друг начин $$ЗАПАЗИ
документът, където условието е false
.
Накратко, ако „разстоянието“ е „по-голямо от“ тогава „радиусът“ на „кръга“, тогава обектът „лежи извън“ на кръга и не се „пресича“. В противен случай "така".
Така че това са основите на „дефинирането на „кръг“ за геометрия в колекция и „използването му“ за постигане на нещо като пресечната точка между „Точка“ или друг тип обект в радиуса на „кръга“.