Ainda mais otimizado que o original, agora você pode usar
$expr
dentro de um $match
estágio após o $geoNear
inicial
:db.collection.aggregate([
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 23.027573, 72.50675800000001 ],
},
"distanceField": "distance"
}},
{ "$match": { "$expr": { "$lte": [ "$distance", "$radius" ] } }}
])
Na verdade, um pouco mais ideal do que quando escrito pela primeira vez. Agora podemos apenas
$redact
em vez de $project
o booleano e $match
mais tarde: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"
}
}}
])
Você armazenou as informações exatamente como deveria, mas há uma abordagem diferente para obter os resultados do que você imagina.
O que você deseja usar é um
$geoNear
e especificamente a estrutura de agregação
forma desse operador. Aqui está o que você faz: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 } }
])
Assim, esse formulário permite que a distância do ponto consultado seja "projetada" nos resultados, enquanto a consulta também retornará apenas os documentos mais próximos.
Então você usa uma comparação lógica para ver se o valor de "distância" é menor que "raio", portanto dentro do círculo.
Finalmente, você faz a correspondência para filtrar apenas os resultados em que a afirmação "dentro" era verdadeira.
Você pode adicionar outras opções a
$geoNear
conforme mostrado na documentação. Eu também sugiro fortemente que seu armazenamento também use o formato GeoJSON, pois provavelmente será mais compatível com quaisquer outras bibliotecas que você possa usar para trabalhar nos resultados obtidos.