I have used the $group pipeline and inside it, I have used $addToSet which has created an array of objects which contains two values - {subGenre (string), flag (bool)}
. In the next pipeline of $project
, I need to run a loop through this array and I need to select only that element of the array where flag
is false.
So my code looks like this:
let data = await Books.aggregate(
[
{
$group: {
_id: genre,
price: { $sum: "$price" },
data: {
$addToSet: {
subGenre: "$subGenre",
flag: "$flagSelectGenre"
}
}
}
}
]
);
This would return documents like:
_id: {
genre: "suspense",
},
price: 10210.6,
data: [
{
subGenre: "Thriller",
flag: false,
},
{
subGenre: "jumpScare",
flag: true,
}
{
subGenre: "horror",
flag: false,
}
]
After this, I need to run a $project
pipeline where I have to only project that element of the data array where the flag
is true. The flag will be true for only one element.
$project: {
price: "$price",
subGenre: {$...... } // some condition on data array??
}
The final output should look like this:
price: 10210.6,
subGenre: "jumpScare",
CodePudding user response:
You can do it like this:
$filter
- to filter items from data array, where flag property is equal to true.$first
- to get first item from above array.$getField
- to get value of subGenre property of the above item.
db.collection.aggregate([
{
"$project": {
"_id": 0,
"price": 1,
"data": {
"$getField": {
"field": "subGenre",
"input": {
"$first": {
"$filter": {
"input": "$data",
"cond": "$$this.flag"
}
}
}
}
}
}
}
])
CodePudding user response:
You can use $filter
array operator to loop and filter elements by required conditions,
$filter
to iterate loop ofdata
array, ifflag
is true then return element$let
to define a variable and store the above filter result$first
to return the first element from the filtered result, you can also use$arrayElemAt
if you are using lower version of the MongoDB
{
$project: {
price: 1,
subGenre: {
$let: {
vars: {
data: {
$filter: {
input: "$data",
cond: "$$this.flag"
}
}
},
in: { $first: "$$data.subGenre" }
}
}
}
}
Another approach using $indexOfArray
and $arrayElemAt
operators,
$indexOfArray
will find the matching element index of the array$arrayElemAt
to get specific element by specifying the index of the element
{
$project: {
price: 1,
subGenre: {
$arrayElemAt: [
"$data.subGenre",
{ $indexOfArray: ["$data.flag", true] }
]
}
}
}