Home > OS >  How can I populate the fields after running the aggregation mongodb
How can I populate the fields after running the aggregation mongodb

Time:10-24

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).

  • Related