Reputation:
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
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" }
}
}
])
Upvotes: 1
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