I'm using NestJS with Mongoose, I have 2 Collections, Territories and Clinics
First I search for territories near the user
async findAllByLocation(location: Location) {
const territories = await this.territoryModel.find({
location: {
$near: {
$geometry: {
type: 'Point',
coordinates: [location.lat, location.long],
},
},
},
});
return territories.map((territory) => {
return {
_id: territory._id,
name: territory.name,
};
});
}
Then the clinic service utilizes this function to fetch the clinic that have any territory from the returned array
async getClinicsByLocation(location: any): Promise<any> {
const territories = await this.territoryService.findAllByLocation(location);
const clinics = await this.clinicModel.find({
territory: { $in: territories.map((t) => t._id) },
});
return clinics;
}
My issue now is that the territories array was sorted from the nearest to the farthest but the clinics are in random order so the clinics have territories farther than others in the response
One solution is to get clinics per each territory alone then merge the arrays but it's not time or performance efficient
Any Idea ?
CodePudding user response:
I think you can do it in one aggregation query. Also an input and output example will be helpful.
By the way, for your queries I think you want:
- Get all territories near to a position
- Return only the
_idandname - Search clinics which
territoryfield is the same as the_idfromterritories.
So I think this can be accomplished in one query like this:
db.territories.aggregate([
{
$geoNear: {
near: {
type: "Point",
coordinates: [location.lat, location.long]
},
distanceField: "dist.calculated"
}
},
{
$project: {
name: 1
}
},
{
$lookup: {
from: "clinics",
localField: "_id",
foreignField: "territory",
as: "clinics"
}
},
{
$unwind: "$clinics" // optional; it depends the output you want
}
])
And the result is something like:
{
"_id":2,
"name":"territory name 2",
"clinics":{
"_id":ObjectId("61ea8a20f90aaa6f3e23efac"),
"territory":2,
"name":"clinic2"
}
}{
"_id":1,
"name":"territory name 1",
"clinics":{
"_id":ObjectId("61ea8a20f90aaa6f3e23efab"),
"territory":1,
"name":"clinic1"
}
}{
"_id":3,
"name":"territory name 3",
"clinics":{
"_id":ObjectId("61ea8a20f90aaa6f3e23efad"),
"territory":3,
"name":"clinic3"
}
}
I've used mongo $geoNear example as input data and in all executions the order is the same.
