Как получить список уникальных элементов каждого типа конкретного поля - MongoDB - PullRequest
0 голосов
/ 26 мая 2020

Предположим, у нас есть следующая коллекция

[
    {
        'item' : 'A',
        'colors' : [
               'a1', 'a2', 'a3'
        ]
    },
    {
        'item' : 'B',
        'colors' : [
               'b1', 'b2', 'b3'
        ]
    },
    {
        'item' : 'A',
        'colors' : [
               'c1', 'c2', 'c3'
        ]
    },
    {
        'item' : 'A',
        'colors' : [
               'd1', 'd2', 'd3'
        ]
    }
]

Я хочу получить отдельные значения для каждого типа поля. Например, в приведенной выше коллекции я хочу получить следующий результат:

[
    {
        'item' : 'A',
        'colors' : [
               'a1', 'a2', 'a3','c1', 'c2', 'c3','d1', 'd2', 'd3'
        ]
    },
    {
        'item' : 'B',
        'colors' : [
               'b1', 'b2', 'b3'
        ]
    }
]

Я попробовал выполнить следующий запрос: db.collection.aggregate([{$group:{_id:'$item',colors:{$addToSet : '$colors'}}}]). Но при этом добавляется каждый отдельный список, а не создается один список только значений. Примерно так.

[
    {
        'item' : 'A',
        'colors' : [
               ['a1', 'a2', 'a3'],['c1', 'c2', 'c3'],['d1', 'd2', 'd3']
        ]
    },
    {
        'item' : 'B',
        'colors' : [
               'b1', 'b2', 'b3'
        ]
    }
]

Что мне изменить в моем запросе? Заранее большое спасибо за вашу помощь.

1 Ответ

0 голосов
/ 26 мая 2020

Используйте $ unwind для преобразования полей массива. Пример

db.collection.aggregate([
  {
    // Output a document for each color values.
    $unwind: "$colors"
  },
  {
    $group: {
      // Groups the documents by item value
      _id: "$item",
      uniqueColorValues: {
        // Set - Store unique values
        // Add the value to array if it is not present
        $addToSet: "$colors"
      }
    }
  }
])

Чтобы получить отсортированный результат, вы должны снова применить размотку и группу, как показано ниже. Пример

db.collection.aggregate([
       {
        // Output a document for each color values.
        $unwind: "$colors"
      },
      {
        $group: {
          // Groups the documents by item value
          _id: "$item",
          uniqueColorValues: {
            // Set - Store unique values
            // Add the value to array if it is not present
            $addToSet: "$colors"
          }
        }
      },
      {
        // Transform again with color values
        $unwind: "$uniqueColorValues"
      },
      {
        // Sort the records with array value color
        $sort: {
          "uniqueColorValues": 1
        }
      },
      {
        // Regroup with _id value item
        "$group": {
          "_id": "$_id",
          // Push the values to array this will preserve the array elemets order
          "uniqueColorValues": {
            "$push": "$uniqueColorValues"
          }
        }
      },
      {
     // Apply the sort on item value.
        $sort: {
          "_id": 1
        }
      }
    ])

Подробную информацию о стадии конвейера агрегации можно найти здесь .

...