Reputation: 636
I've a collection that have this documents:
{
sku: 1,
values: [{x: false, z: 100}]
}
{
sku: 1,
values: [{z: 100}]
}
{
sku: 2
values: [{x: false, z: 100}]
}
Note that the document with
sku
2
is not duplicated but it have the keyx
in a object inside an array.
How do i query the documents grouping by sku
and get the one that does not have the key x
but at the same time also get the sku
that is not duplicated but have the x
key?
The result that i expect is:
{
sku: 1,
values: [{z: 100}]
}
{
sku: 2,
values: [{x: false, x: 100}]
}
I want to ignore a document if it is duplicated by the key sku
and have the keyx: false
but if the document is not duplicated by sku
to get it anyway
Upvotes: 1
Views: 258
Reputation: 49985
So rephrasing your requirements: you want to filter out all values with x: false
if there's more than one document with particular sku
You need Aggregation Framework's $group to get all the data for single sku
. Then you can run $reduce with $concatArrays to flatten values
array and $filter as a last step to apply your business rule:
db.collection.aggregate([
{
$group: {
_id: "$sku",
count: { $sum: 1 },
values: { $push: "$values" }
}
},
{
$addFields: {
values: {
$reduce: {
input: "$values",
initialValue: [],
in: { $concatArrays: [ "$$value", "$$this" ] }
}
}
}
},
{
$project: {
_id: 0,
sku: "$_id",
values: {
$filter: {
input: "$values",
cond: {
$or: [
{ $eq: [ "$count", 1 ] },
{ $ne: [ "$$this.x", false ] }
]
}
}
}
}
}
])
Upvotes: 1