0

Could you please help me to write some sort of aggregation query using mongodb.

I have next data structure.

[
    {
        id: 1,
        shouldPay: true,
        users: [
            {
                id: 100,
                items: [{...}],
                tags: ['a', 'b', 'c', 'd']
            },
            {
                id: 100,
                items: [{...}],
                tags: ['b', 'c', 'd']
            },
            {
                id: 100,
                items: [{...}],
                tags: ['c', 'd']
            }
        ],

    }
]

In result I want to get something like that:

[
    {
        id: 1,
        shouldPay: true,
        user: {
            id: 100,
            items: [{...}],
            tags: ['a', 'b', 'c', 'd']
        }

    }
]

The main idea is to select a specific user that has "a" letter or list of letters ['a', 'b'] in tags.

Bob Dylan
  • 91
  • 1
  • 9

2 Answers2

2

You can use below aggregation

Use $match at the starting of the pipeline to filter out the documents which don't contain "a" and "b" in tags array. And then use $filter with $setIsSubset to filter out the nested array.

$arrayELemAt to return the specified element from the array.

db.collection.aggregate([
  { "$match": { "users.tags": { "$in": ["a", "b"] }}},
  { "$project": {
    "users": {
      "$arrayElemAt": [
        { "$filter": {
          "input": "$users",
          "cond": { "$setIsSubset": [["a", "b"], "$$this.tags"] }
        }},
        0
      ]
    }
  }}
])
Ashh
  • 44,693
  • 14
  • 105
  • 132
0

You need to use $unwind along with $filter:

db.collection.aggregate([
      {
        $unwind: "$users"
      },
      {
        $match: {
          "users.tags": "a"
        }

      }
    ])

Result:

[
  {
    "_id": ObjectId("5a934e000102030405000000"),
    "id": 1,
    "shouldPay": true,
    "users": {
      "id": 100,
      "tags": [
        "a",
        "b",
        "c",
        "d"
      ]
    }
  }
]
Atish
  • 4,277
  • 2
  • 24
  • 32
  • not the best idea, as can be the situation that you had more than 20k records and unwind produce a big amount additional records per document – Bob Dylan Nov 18 '18 at 14:10