mongodb nested object lookup

33 Views Asked by At

I want to reach each subHobbies in hobbies schema but I cant figure it out how to do it properly. Can anyone help me with this?

{
  $lookup: {
    from: "hobbies",
    let: {
      vid: "$surveyTargetHobbies",
    },
    pipeline: [
      {
        $match: {
          $expr: {
            $in: [
              "$_id",
              {
                $map: {
                  input: "$$vid",
                  in: {
                    $toObjectId: "$$this",
                  },
                },
              },
            ],
          },
        },
      },
    ],
    as: "surveyTargetHobbies",
  },
},

I have subHobbies id array as surveyTargetHobbies. I want to see subHobbies titles with this lookup but i cant get subHobbies object in hobbies schema.

{
  "_id": {
    "$oid": "66012b133fa457ed3a999ca7"
  },
  "surveyName": "new survey",
  "surveyStartDate": {
    "$date": "2024-03-26T21:00:00.000Z"
  },
  "surveyEndDate": {
    "$date": "2024-03-29T21:00:00.000Z"
  },
  "surveyTargetGender": "all",
  "surveyTargetHobbies": [
    "6547a0f8aa29e1d75ba8d8a2",
    "6547a0f9aa29e1d75ba8d8a4"
  ],
  "createdAt": {
    "$date": "2024-03-25T07:43:15.298Z"
  },
  "updatedAt": {
    "$date": "2024-03-25T07:43:18.314Z"
  },
}

this part survey schema data

{
  "_id": {
    "$oid": "6547a0e0e1ed3d290303c04f"
  },
  "title": "Dating",
  "subHobbies": [
    {
      "title": "Long-term Relationship",
      "_id": {
        "$oid": "6547a0f8aa29e1d75ba8d8a2"
      }
    },
    {
      "title": "Short-term Relationship",
      "_id": {
        "$oid": "6547a0f9aa29e1d75ba8d8a4"
      }
    }
  ]
}

this part hobbies schema data

1

There are 1 best solutions below

1
nimrod serok On

Edit: according to the added example documents:

db.coll.aggregate([
  {$lookup: {
      from: "hobbies",
      let: {vid: {$map: {
            input: "$surveyTargetHobbies",
            in: {$toObjectId: "$$this"}
      }}},
      pipeline: [
        {$match: {$expr: {
              $gt: [{$size: {$setIntersection: [
                      "$subHobbies._id",
                      "$$vid"
                    ]}}, 0]
        }}},
        {$project: {
            _id: 0,
            subHobbies: {$filter: {
                input: "$subHobbies",
                cond: {$in: ["$$this._id", "$$vid"]}
            }}
        }}
      ],
      as: "surveyTargetHobbies"
  }},
  {$set: {surveyTargetHobbies: {
        $reduce: {
          input: "$surveyTargetHobbies.subHobbies.title",
          initialValue: [],
          in: {$concatArrays: ["$$value", "$$this"]}
        }
  }}}
])

See How it works on the mongoDB playground

Original answer, for flat subHobbies:

db.coll.aggregate([
  {$lookup: {
      from: "hobbies",
      let: {
        vid: {$map: {
            input: "$surveyTargetHobbies",
            in: {$toObjectId: "$$this"}
        }}
      },
      pipeline: [
        {$match: {$expr: {$in: ["$_id", "$$vid"]}}},
        {$project: {_id: 0, title: 1}}
      ],
      as: "surveyTargetHobbies"
  }}
])

See How it works on the mongoDB playground