I have a collection like this:
[
{
"name": "Orange",
"variants": [
{
"color": "orange",
"props": []
}
]
},
{
"name": "Banana",
"variants": [
{
"color": "green",
"props": [
{
"uid": 1,
"grade": 3
},
{
"uid": 2,
"grade": 5
},
{
"uid": 3,
"grade": 7
}
]
}
]
}
]
available_props = [1,2]
Now I would like to add to every prop in props
in every variant
a field available
which evaluates if the uid of the respective prop is in available_props
.
Desired outcome:
[
{
"name": "Orange",
"variants": [
{
"color": "orange",
"props": []
}
]
},
{
"name": "Banana",
"variants": [
{
"color": "green",
"props": [
{
"uid": 1,
"grade": 3,
"available": true
},
{
"uid": 2,
"grade": 5,
"available": true
},
{
"uid": 3,
"grade": 7,
"available": false
}
]
}
]
}
]
Thanks for your help!
you could use nested $map
s combined with $mergeObjects
db.collection.aggregate([
{
$addFields: {
variants: {
$map: {
input: "$variants",
as: "variant",
in: {
$mergeObjects: [
"$$variant",
{
props: {
$map: {
input: "$$variant.props",
as: "prop",
in: {
$mergeObjects: [
"$$prop",
{
available: { $in: [ "$$prop.uid", [ 1, 2 ] ] }
}
]
}
}
}
}
]
}
}
}
}
}
])
as a tip if you are familiar with JS you could come up with almost similar logic
js Array.prototype.map
-> mongo $map
js spread operator(...
) -> mongo $mergeObjects
js Array.prototype.includes
-> mongo $in
const doc = {
"name": "Banana",
"variants": [
{
"color": "green",
"props": [
{
"uid": 1,
"grade": 3,
"available": true
},
{
"uid": 2,
"grade": 5,
"available": true
},
{
"uid": 3,
"grade": 7,
"available": false
}
]
}
]
}
const newDoc = {
...doc,
variants: doc.variants.map(variant => ({
...variant,
props: variant.props.map(prop => ({
...prop,
available: [1, 2].includes(prop.uid)
}))
}))
}
console.log(newDoc)