I am using Mongo version 2.2.33. This is for a large project, mostly legacy code, and updating things is not up to me. If I had a newer version of Mongo I would use $indexOfArray, but since I can't, how can I achieve the same thing?
This is the code I wrote before I realized what version of mongo we were using:
exports.getActionHistoryIndex = function (historyArray, deviceId, cb) {
db.actions.aggregate({$indexOfArray: {historyArray, deviceId}}, function (err, index) {
if (err) {
return cb(err)
} else {
return cb(null, index)
}
})
}
When I call the function, like this:
actionRepo.getActionHistoryIndex(action.history, device._id, (err, res) => {
if (err) console.log(err)
console.log(res)
})
I get this error, because $indexOfArray is onlay available after 3.8, I think:
name: 'MongoError',
message: 'Unrecognized pipeline stage name: \'$indexOfArray\'',
ok: 0,
errmsg: 'Unrecognized pipeline stage name: \'$indexOfArray\'',
code: 40324,
codeName: 'Location40324' }
undefined
Is there an ease way to achieve this? Basically, the problem is that I have a db collection with an array that contains objects. I need to be able to search among the objects in the array for a certain _id
and then edit another attribute in the same object. So my plan is to get the index of the correct object, and then use the index to update the attribute that needs to be changed.
Any help is appreciated.
EDIT: This is a sample document from the action
collection.
_id : ObjectId('ABC')
history: [Array]
0: {Object}
device_id: ObjectId("123")
triggered: false
1: {Object}
device_id: ObjectId("456")
triggered: true
Upon receiving user input, I need to change the triggered
boolean. I have the action document ObjectId and I have the device_id that corresponds to the different objects in the history
array. So I'm looking for a query/update that will allow me to change the triggered
boolean.
EDIT2: This is the function I have after reading answers:
exports.updateHistory = function (action, deviceId, triggered, cb) {
console.log(action._id + ' || action._id')
console.log(deviceId + ' || deviceId')
console.log(triggered + ' || triggered')
db.actions.updateOne(
{_id: action._id, 'history.device_id': deviceId},
{$set: { 'history.$.triggered': triggered }},
{w: 1},
function (err, results) {
if (err) {
return cb(err)
}
return cb(null, results)
})
}
All of the log statements are correct, and I don't get any errors, but my documents aren't changed at all. This function gets called three times for three different action
documents. The triggered
value for all 3 is currently false. When this function runs, the triggered
value passed in is true
, but it doesn't update the document. Any suggestions?