Thậm chí còn tối ưu hơn bản gốc, giờ đây bạn có thể sử dụng $expr
trong $match
giai đoạn sau $geoNear
đầu tiên
:
db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
{ "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])
Trên thực tế, tối ưu hơn một chút so với lần đầu tiên được viết. Giờ đây, chúng tôi chỉ có thể $redact
chứ không phải là $project
boolean và $match
sau:
db.collection.aggregate([
// Match documents "near" the queried point
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
// Calculate if distance is within radius and remove if not
{ "$redact": {
"$cond": {
"if": { "$lte": [ "$distance", "$radius" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])
Bạn đã lưu trữ thông tin chính xác theo cách bạn nên làm, nhưng có một cách tiếp cận khác để nhận được kết quả hơn bạn nghĩ.
Những gì bạn muốn sử dụng là $geoNear
và cụ thể là khung tổng hợp
dạng của toán tử đó. Đây là những gì bạn làm:
db.collection.aggregate([
// Match documents "near" the queried point
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
// Calculate if distance is within radius
{ "$project": {
"location": 1,
"radius": 1,
"distance": 1,
"within": { "$lte": [ "$distance", "$radius" ] }
}},
// Match only documents within the radius
{ "$match": { "within": true } }
])
Vì vậy, biểu mẫu đó cho phép khoảng cách từ điểm được truy vấn được "chiếu" trong kết quả, trong khi truy vấn cũng sẽ chỉ trả về các tài liệu gần nhất.
Sau đó, bạn sử dụng phép so sánh logic để xem liệu giá trị "khoảng cách" có nhỏ hơn "bán kính", do đó nằm trong vòng kết nối hay không.
Cuối cùng, bạn đối sánh để chỉ lọc ra những kết quả mà khẳng định "bên trong" đó là đúng.
Bạn có thể thêm các tùy chọn khác vào $geoNear
như được hiển thị trong tài liệu. Tôi cũng đặc biệt khuyên rằng bộ nhớ của bạn cũng nên sử dụng định dạng GeoJSON vì định dạng này có khả năng tương thích hơn với bất kỳ thư viện nào khác mà bạn có thể sử dụng để làm việc trên kết quả thu được.