I am trying to populate the fields in the result that I got from running the $geoNear
aggregation but I don't know how can I do it. I tried $lookup
but it gave me the same result.
const users = await locations.aggregate([
{
$geoNear: {
near: {
type: "Point",
coordinates: req.body.coordinates,
},
maxDistance: req.body.maxDistance,
distanceField: "dist.calculated",
spherical: true,
},
{
$lookup: {
from: "users",
localField: "userId", // getting empty array of users
foreignField: "_id",
as: "users",
},
}, // getting all users data
{
$project: {
_id: 1,
name: 1,
profession: 1,
},
}, // only getting `_id`
},
]);
Result:
{
{
"_id": "63555c4f29820cf3c7667eb5",
"userId": "63555c2629820cf3c7667eac",
"location": {
"coordinates": [
2.346688,
48.858888
],
"type": "Point"
},
"createdAt": "2022-10-23T15:22:55.820Z",
"updatedAt": "2022-10-23T16:08:59.979Z",
"__v": 2,
"dist": {
"calculated": 42.95013302539912
}
}
}
I want to populate the name
field from the users
schema and to do so I have used the ref
of the users
schema in the locations
schema.
users schema:
{
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
unique: true,
index: true,
},
}
location Schema:
{
userId: {
type: mongoose.Schema.ObjectId,
ref: "users",
required: true,
},
location: {
type: {
type: String,
enum: ["Point"],
default: "Point",
},
coordinates: {
type: [Number],
default: [0, 0],
},
},
},
How can I populate fields in my aggregation result?
Also, How can I remove all the fields and output the names and email only from the users
schema?
CodePudding user response:
You should include your $lookup
stage as following:
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user",
}
},
{
"$replaceRoot": {
"newRoot": {
"$arrayElemAt": [
"$user",
0
]
}
}
},
{
$project: {
_id: 1,
name: 1,
profession: 1
}
}
It seems like you tried to match an ObjectId
to a String (property name
), which will never match. Using the aggregation step above you should receive a populated user array containing exactly one entry. After that you can project the result and transform the array to a plain object (if needed).