I am ierating through an object with key value pairs, where the value is an array of objects. If certain prop (lets say title) is already in the db, I do not want to save that object containing same title. When I hard code the title as a string, it works fine If I pass a map iteration to $in, nothing works (the objects are being saved in all cases then). What am I doing wrong?
for (let key in reports) {
const condition = reports[key].map((x) => {
return x.title;
});
await Product.findOneAndUpdate({
"name": key
},
[
{
"$set": {
"reports": {
"$cond": [
{
"$in": [
//this works as expected:
"IAmProduct1",
"$reports.title"
//this does Not work when iterating:
// condition,
// "$reports.title"
]
},
"$reports",
{
"$concatArrays": [
"$reports",
reports[key]
]
}
]
}
}
}
], {new: true})
}
Function reports[key].map((x) => { return x.title; })
(or just reports[key].map(x => x.title)
) returns an array rather than a string:
const reports = { key1: [{ title: "IAmProduct1" }] };
print(reports['key1'].map(x => x.title));
-> [ 'IAmProduct1' ]
Which is not
'IAmProduct1'
Maybe $setUnion would be simpler:
Product.findOneAndUpdate(
{ "name": key },
[
{
$set: {
reports: { $setUnion: ["$reports", reports[key]] }
}
}
]
)
Or put the condition in your filter, should be much more efficient:
Product.findOneAndUpdate(
{ "name": key, "reports.title": {$ne: condition } },
[
{
"$set": {
"reports": {
"$concatArrays": [
"$reports",
reports[key]
]
}
}
}
],
{ new: true }
)