हाँ, यह संभव है। आप बस $geoNear
. का उपयोग करें बजाय। कैच से सावधान रहें और ध्यान से पढ़ें।
यह मानते हुए कि आपका इरादा "travelDistance"
. जैसे फ़ील्ड को स्टोर करने का है दस्तावेज़ पर यह इंगित करने के लिए कि ऐसी कोई भी खोज "भीतर" होनी चाहिए जो वैध होने के लिए पूछे गए बिंदु से दूरी प्रदान करती है। फिर हम बस $redact
. के साथ स्थिति की क्वेरी और मूल्यांकन करते हैं :
db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [x,y]
},
"spherical": true,
"distanceField": "distance"
}},
{ "$redact": {
"$cond": {
"if": { "$lte": [ "$distance", "$travelDistance" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
एकमात्र पकड़ यह है कि $geoNear
जैसे $near
पहले स्थान पर केवल "निकट" दस्तावेजों की एक निश्चित संख्या लौटाएगा। आप इसे विकल्पों के साथ ट्यून कर सकते हैं, लेकिन सामान्य क्वेरी फ़ॉर्म के विपरीत, यह मूल रूप से गारंटी देता है कि अंतिम लौटाए गए परिणाम निर्दिष्ट "निकटतम" संख्याओं से कम होंगे।
जब तक आप इसके बारे में जानते हैं, तब तक यह पूरी तरह मान्य है।
वास्तव में यह एक दायरे में "नजदीकी" योग्यता से निपटने का सामान्य तरीका है।
आपके पास निर्देशांक कैसे संग्रहीत हैं, इसके अनुसार "दूरी" से भी अवगत रहें। लीगेसी समन्वय जोड़े के रूप में दूरियां रेडियन में होंगी जिन्हें किलोमीटर या मील में बदलने के लिए आपको शायद गणित करना होगा।
यदि जियोसन का उपयोग कर रहे हैं, तो दूरियों को हमेशा मीटर में मानक प्रारूप के रूप में माना जाता है।
सभी गणित के नोट्स दस्तावेज़ीकरण में हैं।
<ब्लॉककोट>
नायब पढ़ें $geoNear
दस्तावेज़ीकरण ध्यान से। "spherical"
. जैसे विकल्प "2dsphere"
. के लिए आवश्यक हैं अनुक्रमणिका, जैसे कि आपके पास वास्तविक विश्व निर्देशांक के लिए होना चाहिए। साथ ही "limit"
आगे ट्रिमिंग के लिए डिफ़ॉल्ट 100 दस्तावेज़ परिणाम को बढ़ाने के लिए लागू करने की आवश्यकता हो सकती है।
जैसा कि टिप्पणियों में स्प्रिंग मोंगो का उल्लेख है, तो यहाँ मूल रूप से उसके लिए वही काम किया गया है:
Aggregation aggregation = newAggregation(
new AggregationOperation() {
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject("$geoNear",
new BasicDBObject(
"near", new BasicDBObject(
"type","Point")
.append("coordinates", Arrays.asList(20,30))
)
.append("spherical",true)
.append("distanceField","distance")
);
}
},
new AggregationOperation() {
@Override
public DBObject toDBObject(AggregationOperationContext context) {
return new BasicDBObject("$redact",
new BasicDBObject(
"$cond", Arrays.asList(
new BasicDBObject("$lte", Arrays.asList("$distance", "$travelDistance")),
"$$KEEP",
"$$PRUNE"
)
)
);
}
}
);