Ano, je to možné. Stačí použít $geoNear
namísto. Dejte si pozor na úlovky a pozorně čtěte.
Za předpokladu, že vaším záměrem je uložit pole, jako je "travelDistance"
aby bylo v dokumentu uvedeno, že všechna taková vyhledávání musí být „v rámci“ uvedené vzdálenosti od dotazovaného bodu, aby byla platná. Poté se jednoduše dotazujeme a vyhodnotíme podmínku pomocí $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"
}
}}
])
Jediný háček je v tom, že $geoNear
stejně jako $near
v první řadě vrátí pouze určitý počet dokumentů „v blízkosti“. Můžete to vyladit pomocí možností, ale na rozdíl od obecného formuláře dotazu to v podstatě zaručuje, že případné vrácené výsledky budou menší než zadaná „nejbližší“ čísla.
Dokud jste si toho vědomi, pak je to naprosto platné.
Je to ve skutečnosti obecný způsob, jak se vypořádat s kvalifikací toho, co je „blízko“ v okruhu.
Uvědomte si také "vzdálenost" podle toho, jak máte uložené souřadnice. Jako starší páry souřadnic budou vzdálenosti v radiánech, které budete pravděpodobně muset spočítat, abyste je mohli převést na kilometry nebo míle.
Pokud používáte GeoJSON, pak jsou vzdálenosti vždy uvažovány v metrech jako standardní formát.
Všechny matematické poznámky jsou v dokumentaci.
N.B Přečtěte si
$geoNear
dokumentaci pečlivě. Možnosti jako"spherical"
jsou vyžadovány pro"2dsphere"
indexy, jaké byste měli mít pro souřadnice reálného světa. Také"limit"
může být nutné použít pro zvýšení nad výchozí hodnotu 100 dokumentu pro další oříznutí.
Vzhledem k tomu, že komentáře zmiňují jarní mongo, zde je v podstatě totéž:
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"
)
)
);
}
}
);