user11553898
user11553898

Reputation:

How to list unique values ​in a MongoDB collection if the values ​are arrays of objects?

I need to output a list of unique values in a collection. I've used the distinct method when the values are either a string or a number. But in this situation, the values are an array of objects.

The simplified model looks like this:

const mongoose = require('mongoose');

const ItemModel = mongoose.Schema({  
  category: [{
    lang: String,
    text: String
  }],
  discount: {
    type: String,
    required: true
  },
  date: {
    type: Date,
    default: Date.now
  }
});

module.exports = mongoose.model('Items', ItemModel);

A typical find() query without parameters produces this result:

[
  {
    "_id": "5fd8712b374a9a1410f786bf",
    "category": [
      {
        "_id": "5fd8712b374a9a1410f786c2",
        "lang": "RU",
        "text": "Домашняя одежда"
      },
      {
        "_id": "5fd8712b374a9a1410f786c3",
        "lang": "EN",
        "text": "Homewear"
      }
    ],
    "discount": "45%",
    "date": "2020-12-12T11:12:37.811Z",
    "__v": 0
  },
  {
    "_id": "5fd4a5b95e1a251ac96b2e08",
    "category": [
      {
        "_id": "5fd4a5b95e1a251ac96b2e0b",
        "lang": "RU",
        "text": "Домашняя одежда"
      },
      {
        "_id": "5fd4a5b95e1a251ac96b2e0c",
        "lang": "EN",
        "text": "Homewear"
      }
    ],
    "discount": "35%",
    "date": "2020-12-12T11:12:37.811Z",
    "__v": 0
  },
  {
    "_id": "5fd49e415e1a251ac96b2dfc",
    "category": [
      {
        "_id": "5fd49e415e1a251ac96b2dff",
        "lang": "RU",
        "text": "Активный отдых"
      },
      {
        "_id": "5fd49e415e1a251ac96b2e00",
        "lang": "EN",
        "text": "Active"
      }
    ],
    "discount": "50%",
    "date": "2020-12-12T10:06:53.120Z",
    "__v": 0
  }
]

I need to output a list of unique "category.text" values where "lang" equals "EN". At the output, we should get an array like this:

[ "Active", "Homewear" ]

How to do it the right way, with good performance? Regards.

Upvotes: 1

Views: 606

Answers (2)

turivishal
turivishal

Reputation: 36104

You can use aggregation pipeline,

  • $unwind to deconstruct category array
  • $match category.lang is EN
  • $group by null, and get unique text using $addToSet
StockModel.aggregate([
  { $unwind: "$category" },
  { $match: { "category.lang": "EN" } },
  {
    $group: {
      _id: null,
      test: { $addToSet: "$category.text" }
    }
  }
])

Playground

Upvotes: 1

Babak Abadkheir
Babak Abadkheir

Reputation: 2350

use aggregation :

take a look at the example below :

StockModel.aggregate([
      {
        $group: {
          _id: 0,
          title: { $addToSet: '$title' },
          stock_id: { $addToSet: '$stock_id' },
        },
      },
    ]);

with aggregation $group you can distinct your collections via filter.

Upvotes: 0

Related Questions