I want to find objects that match the following query and then set the events property to an empty array if it matches. Currently the query I'm using will only update the first embedded object in each document, but I need it to check every embedded object in each document. Here is the query, does anyone know how I can make this work?
const date_check = moment().subtract(10, 'minutes').format('X')
await Accumulator.updateMany(
{ 'data.lastUpdate': { $lt: date_check } },
{
$set: {
'data.$.events': []
}
}
)
The document looks like this...
{
bookmaker: 'Bet365',
sport: 'Football',
data: [
{
lastUpdate: '2372273273',
events: [
... // some event objects
]
},
{
lastUpdate: '2372234421',
events: [
... // some event objects
]
},
{
lastUpdate: '2375343461',
events: [
... // some event objects
]
}
]
}
CodePudding user response:
I think its best to change your schema so lastUpdate
to be a number
for perfomance, and to avoid bugs, check $toInt
, you can do it with code similar to the second query.
Query
- arrayfilters way
- replace "2372273273" with date_check
- filter to keep the documents
- use arrayFilters to make the change only the member-documents that pass the filter
db.collection.update({
"data.lastUpdate": {
"$lt": "2372273273"
}
},
{
$set: {
"data.$[data].events": []
}
},
{
"arrayFilters": [
{
"data.lastUpdate": {
"$lt": "2372273273"
}
}
]
})
Query
- alternative pipeline update way with
$map
- replace "2372273273" with
date_check
- filter to find the document
- update only the members that the filter is true
pipeline update requires MongoDB >= 4.2
db.collection.update({
"data.lastUpdate": {
"$lt": "2372273273"
}
},
[
{
"$set": {
"data": {
"$map": {
"input": "$data",
"in": {
"$cond": [
{
"$lt": [
"$$this.lastUpdate",
"2372273273"
]
},
{
"$mergeObjects": [
"$$this",
{
"events": []
}
]
},
"$$this"
]
}
}
}
}
}
])