GYEONGSEOP KIM
GYEONGSEOP KIM

Reputation: 47

lookup compare collection data with array in aggregate result in mongo DB

i want to compare collection with array in aggregate result

i have following two collection.

  1. chat collection

chat.tags is a array value in reference key come from the tags collection.

"chat": [
    {
      "id": "test1",
      "tags": [
        "AAA",
        "BBB",
        "CCC",
        "AAA"
      ]
    },
    {
      "id": "test2",
      "tags": [
        "AAA",
        "BBB",
        "CCC"
      ]
    }
  ]
  1. tag collection
  "tag": [
    {
      "id": "1234",
      "key": "AAA",
      "name": "a"
    },
    {
      "id": "1235",
      "key": "BBB",
      "name": "b"
    },
    {
      "id": "1236",
      "key": "CCC",
      "name": "c"
    },
    {
      "id": "1237",
      "key": "DDD",
      "name": "d"
    },
  ]

i want to result that id is "test1" and unique tags in chat collection.

i want to following result using with mongo aggregate. Is it possible with from, let, pipeline when using lookup?

[
  {
    "chat": [
      {
        "id": "test1",
        "setTags": [
          "AAA",
          "BBB",
          "CCC"
        ]
      }
    ],
    "tag": [
    {
       "id": "1234",
       "key": "AAA",
       "name": "a"
     },
     {
       "id": "1235",
       "key": "BBB",
       "name": "b"
     },
     {
       "id": "1236",
       "key": "CCC",
       "name": "c"
     }
    ]
  }
]




please help me.

Upvotes: 1

Views: 490

Answers (1)

Tom Slabbaert
Tom Slabbaert

Reputation: 22316

This can be achieved with a simple $lookup, like so:

db.chat.aggregate([
  {
    $match: {
      id: "test1"
    }
  },
  {
    $lookup: {
      from: "tag",
      localField: "tags",
      foreignField: "key",
      as: "tagDocs"
    }
  },
  {
    $project: {
      chat: [
        {
          id: "$id",
          setTags: "$tags"
        }
      ],
      tag: "$tagDocs"
    }
  }
])

Mongo Playground

  • I didn't fully understand what the output structure you want is but it can easily be changed via a different $project stage.

--- EDIT ---

With Mongo's v3.6 $lookup syntax the pipeline remains the same, just the $lookup stage changes:

{
    $lookup: {
      from: "tag",
      let: {
        tagKeys: "$tags"
      },
      pipeline: [
        {
          $match: {
            $expr: {
              $in: [
                "$key",
                "$$tagKeys"
              ]
            }
          }
        }
      ],
      as: "tagDocs"
    }
  },

Mongo Playground

Upvotes: 1

Related Questions