Vâng nó có thể. Bạn chỉ cần sử dụng $geoNear
thay thế. Hãy coi chừng những thông tin bắt được và đọc kỹ.
Giả sử rằng mục đích của bạn là lưu trữ một trường chẳng hạn như "travelDistance"
để chỉ ra trên tài liệu rằng bất kỳ tìm kiếm nào như vậy phải nằm "trong" khoảng cách được cung cấp từ điểm được truy vấn để có giá trị. Sau đó, chúng tôi chỉ cần truy vấn và đánh giá điều kiện với $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"
}
}}
])
Bí quyết duy nhất là $geoNear
giống như $near
sẽ chỉ trả về một số tài liệu nhất định "gần" ở vị trí đầu tiên. Bạn có thể điều chỉnh điều đó bằng các tùy chọn, nhưng không giống như biểu mẫu truy vấn chung, điều này về cơ bản đảm bảo rằng kết quả trả về cuối cùng sẽ ít hơn các số "gần nhất" được chỉ định.
Miễn là bạn nhận thức được điều đó, thì điều này hoàn toàn hợp lệ.
Trên thực tế, đó là cách chung để đối phó với điều kiện "gần" trong bán kính.
Cũng cần lưu ý về "khoảng cách" theo cách bạn có tọa độ được lưu trữ. Vì các cặp tọa độ kế thừa, khoảng cách sẽ tính bằng radian mà bạn có thể sẽ cần thực hiện phép toán để chuyển đổi thành ki lô mét hoặc dặm.
Nếu sử dụng GeoJSON, thì khoảng cách luôn được coi là mét, làm định dạng tiêu chuẩn.
Tất cả các ghi chú toán học đều có trong tài liệu.
N.B Đọc
$geoNear
tài liệu cẩn thận. Các tùy chọn như"spherical"
được yêu cầu cho"2dsphere"
chỉ mục, chẳng hạn như bạn nên có cho các tọa độ trong thế giới thực. Ngoài ra"limit"
có thể cần được áp dụng để tăng hơn 100 kết quả tài liệu mặc định, để cắt thêm.
Như các nhận xét đề cập đến mùa xuân mongo, về cơ bản đây là điều tương tự được thực hiện cho điều đó:
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"
)
)
);
}
}
);