सबसे पहले मैं दृढ़ता से सलाह देता हूं कि यदि आप वास्तविक विश्व निर्देशांक पर भू-स्थानिक प्रश्नों का इरादा रखते हैं तो आप अपने संग्रह के लिए "2dsphere" अनुक्रमणिका बनाएं।
उन अन्य इंडेक्स को छोड़ना सुनिश्चित करें जिनके साथ आप खेल रहे होंगे:
db.records.dropIndexes();
db.records.createIndex({ "addresses.loc": "2dsphere" })
आप जो चाहते हैं उसे करने के लिए, पहले थोड़ा सा संशोधन देखें जिसमें includeLocs भी शामिल है $geoNear
का विकल्प
db.records.aggregate([
{ "$geoNear": {
"near": [ -73.9815103, 40.7475731 ],
"spherical": true,
"distanceField": "distance",
"includeLocs": "locs"
}}
])
अब आप ऐसा आउटपुट देखेंगे जो इस तरह दिखता है:
{
"_id" : ObjectId("592d0c78555a7436b0883960"),
"userid" : 7,
"addresses" : [
{
"apporx" : 50,
"loc" : [
-73.98137109999999,
40.7476039
]
},
{
"apporx" : 15,
"loc" : [
-73.982002,
40.74767
]
},
{
"apporx" : 10,
"loc" : [
-73.9819567,
40.7471609
]
}
],
"distance" : 0.0000019174641401278624,
"locs" : [
-73.98137109999999,
40.7476039
]
}
तो जो वापस आया वह न केवल उस बिंदु की दूरी था जो निकटतम था बल्कि "कौन सा" स्थान इस्तेमाल किया गया था।
इसलिए यदि आप $filter
चाहते हैं
मूल सरणी निकटतम लौटने के लिए, तो आप यह कर सकते हैं:
db.records.aggregate([
{ "$geoNear": {
"near": [ -73.9815103, 40.7475731 ],
"spherical": true,
"distanceField": "distance",
"includeLocs": "locs"
}},
{ "$addFields": {
"addresses": {
"$filter": {
"input": "$addresses",
"as": "address",
"cond": { "$eq": [ "$$address.loc", "$locs" ] }
}
}
}}
])
और वह केवल उस मैच के साथ सरणी लौटाता है:
{
"_id" : ObjectId("592d0c78555a7436b0883960"),
"userid" : 7,
"addresses" : [
{
"apporx" : 50,
"loc" : [
-73.98137109999999,
40.7476039
]
}
],
"distance" : 0.0000019174641401278624,
"locs" : [
-73.98137109999999,
40.7476039
]
}