Mongo: How to update multiple records in one query - node.js

Hi i need a help for mongodb update multiple records in one query by array value:
For This Data
{
"_id" : ObjectId("5edcd82197ace301c45ccb02"),
"date" : NumberInt(20200607),
"result" : [
{
"_id" : ObjectId("5edcd82197ace301c45ccb03"),
"balance" : NumberInt(300),
},
{
"_id" : ObjectId("5edcd82197ace301c45ccb04"),
"balance" : NumberInt(200),
}
]
}
Query
use auth;
db.getCollection("dailyreportbalace").updateMany(
[{
"_id": ObjectId("5edcd82197ace301c45ccb02"),
"result._id": ObjectId("5edcd82197ace301c45ccb03")
},{
"_id": ObjectId("5edcd82197ace301c45ccb02"),
"result._id": ObjectId("5edcd82197ace301c45ccb04")
}],
[{
"$set": { "result.$.balance": NumberInt(60) }
},{
"$set": { "result.$.balance": NumberInt(80) }
}],
{upsert: true, multi: true}
)
Error Query
E QUERY [js] Error: the update operation document must contain atomic operators :

Please consider my comment.
You are doing it wrong, if you look at the update docs, the first parameter is query, and it can't be an array.
You need to use filtered positional operator. Something like below:
db.getCollection("dailyreportbalace").updateMany(
{"_id": ObjectId("5edcd82197ace301c45ccb02")},
{
"$set": {
"result.$[elem1].balance": NumberInt(60),
"result.$[elem2].balance": NumberInt(80) }
},
{
upsert: true,
multi: true,
arrayFilters: [
{"elem1._id": ObjectId("5edcd82197ace301c45ccb03")},
{"elem2._id": ObjectId("5edcd82197ace301c45ccb04")}]
}
)

Related

Mongoose, update values in array inside an object in an array

How can i update values in array inside an object in an array.
{
"_id" : ObjectId("63c7ca9584535c160ee4aaed"),
"status" : "REJECTED",
"steps" : [
{
"_id" : ObjectId("63c7ca9884535c160ee4ab03"),
"status" : "REJECTED",
"stepUsers" : [
{
"_id" : ObjectId("63c7ca9884535c160ee4ab04"),
"status" : "REJECTED",
}
]
},
]
}
I tried to update using arrayFilters but that didn't work. Mongo throw an error MongoServerError: Found multiple array filters with the same top-level field name steps
Collection.updateOne({
_id: id
}, {
$set: {
"steps.$[steps].stepUsers.$[stepUsers].status": 'PENDING',
}
}, {
arrayFilters: [
{ "steps._id": step._id },
{ "steps.stepUsers._id": stepUser._id }
]
})
I need to update steps.stepUsers.status in the collection.
Try to change the arrayFilters: "steps.stepUsers._id" -> "stepUsers._id"
since arrayFilters is referencing the string inside the [], not the path to it.
Collection.updateOne({
_id: id
},
{
$set: {
"steps.$[steps].stepUsers.$[stepUsers].status": "PENDING",
}
},
{
arrayFilters: [
{
"steps._id": step._id
},
{
"stepUsers._id": stepUser._id
}
]
})
See how it works on the playground example

Update all the key values of a dynamic object in MongoDB

I have a object which has dynamic keys all the values in that are numeric integers, i like to update all the key values in that object
{
"_id" : ObjectId("6395fc7b1c5a0c4a5fc9bd8e"),
"users" : [
ObjectId("638da89d0066308efe081709"),
ObjectId("63844feadf507942caaf90e3"),
ObjectId("638455e5fa983e9cf84c0f3f")
],
"type" : "GROUP",
"unReadCount" : {
"638da89d0066308efe081709" : 0,
"63844feadf507942caaf90e3" : 0,
"638455e5fa983e9cf84c0f3f" : 0
},
"createdAt" : ISODate("2022-12-11T21:21:23.815+05:30"),
"updatedAt" : ISODate("2022-12-11T22:48:33.953+05:30"),
"__v" : 0
},
I want to increment the unReadCount entire object values, please note the unReadCount object keys are not static it varies document to document. I tried with normal $inc operator it thrown error stating that has the field 'unReadCount' of non-numeric type object" $ wouldn't work as its not an array.
Please note that am trying to achieve this in MongoDB, i can do this via JS code by fetching the records and looping through it, but i like to do it in MongoDB/Mongoose. Any clue/help is appreciated
I think here is what you need
db.tests.updateMany({},[
{
$addFields: {
unReadCountArray: { $objectToArray: "$unReadCount" }
}
},
{
$addFields: {
unReadCountArray: {
$map: {
input: "$unReadCountArray",
as: "unReadCount",
in:
{
$mergeObjects: [ { k:"$$unReadCount.k", v: {$add: ["$$unReadCount.v", 1] }}, null ]
}
}
}
}
},
{
$addFields: {
unReadCount: {
$arrayToObject: '$unReadCountArray'
}
}
},{
$unset:'unReadCountArray'
},
{ $set: { modified: "$$NOW"} }])

Mongoose updateOne and $switch

In one of my database collections I want to update an entry of an array in my document depending of a condition. My documents are like this:
{
_id : ...
myarray: [
{
field1: false,
field2: false,
...
},
...
]
}
I want to set field2 dependent of the old value of field1 and then change the value of field1 too. I tried it like this with no success:
Document.updateOne({
person : req.body.person
},
{
$set: {
"myarray.$[elem].field2" : {
$switch : {
branches : [
{ case : { $eq : [ "marry.$[elem].field1", true ]}, then : false }
],
default : req.body.field2
},
"myarray.$[elem].field2" : req.body.field1
}
},{
arrayFilters: [
{ "elem._id" : { $in : req.body.myEntries }}
],
"multi" : true
})
.exec(...)
Can you help me? Thanks in advance!

MongoDB - Update objects remove item in send array in object (nested updating)

this is my mongodb object
{
"_id" : ObjectId("4faaba123412d654fe83hg876"),
"user_id" : 123456,
"posters" : [ 123456,1111,456789,3333]
}
i want to add an item to posters array , or remove one how could i do it ?
its nested updating.
i saw some question around stackoverflow , but i didnt found any answer how to remove object from the array , lets say 3333 there .
so the result will be :
{
"_id" : ObjectId("4faaba123412d654fe83hg876"),
"user_id" : 123456,
"posters" : [ 123456,1111,456789]
}
Use $pull.
db.collection.update(
{ posters: "3333" },
{ $pull: { posters: "3333" } },
{ multi: true }
)
Use $push to add something into an array :
db.collection.update(
{ $push:
{
"posters" : "0000"
}
}
)
Use $pull to remove something from an array:
db.collection.update(
{ $pull:
{
"posters" : "3333"
}
}, True
)

How to find the count of objects in an array which is a value for a key in all mongodb documents in a collection

Here is the collection.
{{
"id" : "123",
"likes" : [ {
"member" : "3041"
},
{
"member" : "3141"
}]
},
{
"id" : "124",
"likes" : [ {
"member" : "3241"
},
{
"member" : "3241"
},
{
"member" : "3341"
}]
}}
How to retrieve the count of number of objects of likes key for each document?
In this format:
[{
"id" : "123",
"likesCount" : 2
},
{
"id" : "124",
"likesCount" : 3
}]
This should do it for you:
db.collection.aggregate([
{
$project: {
_id: 0,
id: 1,
likesCount: {
$size: "$likes"
}
}
}
])
You are using an aggregation and in the $project part of it use $size to get the length of the array.
You can see it working here
I think you have to map the collection to transform the objects within it into the shape you want.
In this case we get the object and extract the id and instead of all the likes we just get the length of them.
let newCollection = collection.map(obj => ({
id: obj.id,
likesCount: obj.likes.length
}));

Resources