MongoDB conditional $lookup, is it possible?

Viewed 35

so I stumbled on this issue. I have this kind of document:

{
"day": 1,
"title": "Lorem ipsum dolor sit amet",
"data": [
    {
        "type": "body",
        "content": "Lorem ipsum dolor sit amet"
    },
   {
        "type": "content_list",
        "content": [
            {
                "id": "6312b5bd0fb68141c6bdc4d0",
            },
            {
                "id": "6311c6c50fb68141c6b97710",
            },
        ]
    },
    {
        "type": "body",
        "content": "Lorem ipsum dolor sit amet"
    },
    {
        "type": "content_list",
        "content": [
            {
                "id": "6312b5bd0fb68141c6bdc4d0",
            },
            {
                "id": "6311c6c50fb68141c6b97710",
            },
        ]
    }]}

There is a list of different content types in the data field, if the content type is “content_list” then I would like to do a $lookup using the id. Is it possible to do a conditional $lookup ? In the end I need the same structure but with each id populated.

{
"day": 1,
"title": "Lorem ipsum dolor sit amet",
"data": [
    {
        "type": "body",
        "content": "Lorem ipsum dolor sit amet"
    },
   {
        "type": "content_list",
        "content": [
            {
                "id": "6312b5bd0fb68141c6bdc4d0",
                "title" : "AAAA",
                "date": 21-3-2022,
                "duration": 10 min
            },
            {
                "id": "6311c6c50fb68141c6b97710",
                "title" : "EEEE",
                "date": 21-3-2022,
                "duration": 10 min
            },
        ]
    },
    {
        "type": "body",
        "content": "Lorem ipsum dolor sit amet"
    },
    {
        "type": "content_list",
        "content": [
            {
                "id": "6312b5bd0fb68141c6bdc4d0",
                "title" : "BBB",
                "date": 21-3-2022,
                "duration": 10 min
            },
            {
                "id": "6311c6c50fb68141c6b97710",
                "title" : "CCCC",
                "date": 21-3-2022,
                "duration": 10 min
            },
        ]
    }]}
1 Answers

You can use $cond, like this:

EDIT:

db.colA.aggregate([
  {$unwind: "$data"},
  {$lookup: {
      from: "colB",
      localField: "data.content.id",
      foreignField: "id",
      as: "data.contentL"
    }
  },
  {$set: {
    "data.content": {
      $cond: [{$eq: ["$data.type", "content_list"]}, "$data.contentL", "$data.content"]},
    "data.contentL": "$$REMOVE"
  }},
  {$group: {
      _id: {day: "$day", title: "$title"},
      data: {$push: "$data"}
  }},
  {$project: {_id: 0, day: "$_id.day", title: "$_id.title", data: 1}}
])

See how it works on the playground example

Related