MongoDB findAndModify element in array - mongodb

I have the data like below:
{
info:{
id:0000,
name:"Iot name",
vendor:"some vendor",
},
location:[
{
lat:0,
lng:0,
status:3,
locID:"uniqueID0"
},{
lat:1,
lng:1,
status:0,
locID:"uniqueID1"
},{
lat:2,
lng:2,
status:1,
locID:"uniqueID2"
}
]}
Need example like findAndModify or something else similar, to find
in the iots collection, location with a unique ID and change his status.
e.g Find in collection iot, element with id=0000 and location with locID="uniqueID1" and set status for that location into 2
Thanks in advance

Apply the $set operator together with the $ positional operator in your update to change set the status field for that location to 2. The $ positional operator will identify the correct element in the array to update without explicitly specifying the position of the element in the array, thus your final update statement should look like:
db.iost.update(
{
"info.id": 0000,
"location.locID": "uniqueID1"
},
{
"$set": {
"location.$.status": 2
}
}
)

Related

MongoDB: Updating element in array always results in first element updated

TL;DR : Updating element in array always results in first element updated and results differ based on property name of key used in find params
Playground : https://mongoplayground.net/p/-4kGZnxa-WA
I want to update an object in a array and I am using 2 of the object properties to find the object then using $set operator with array.$.updateProperty to update the object
Here is the working playground link of what I want to do:
https://mongoplayground.net/p/dswt8vuzJMc
But I cant reproduce the same when I change a single property name (both in database as well as find parameter) , from the above example I changed property foo to trackID but then only the first element in array is always updated
Playground : https://mongoplayground.net/p/-4kGZnxa-WA
It seems weird as I assumed the property name shouldn't matter as long as it used the same in find params too and its not a keyword like _id
Your update is very close. You need to use "$elemMatch" to identify the specific array position where both conditions match.
N.B.: $ will only update the first matching array element. If you want to update all array elements, use $[], and if you want to update all matching array elements, using "arrayFilters" with $[<indentifier>] is convenient.
db.collection.update({
"_id": ObjectId("62f11e22d99c79532de6ff7f"),
"jobs": {
"$elemMatch": {
"trackID": 0,
"name": "kaisen_track-0_h264_1080p"
}
}
},
{
"$set": {
"jobs.$.status": "Done"
}
})
Try it on mongoplayground.net.

How to change attribute name of the embed type?

How I can change the name of the embed type by query $rename?
{ list_name: [{ name_1: String }] } => { list_name: [{ name_2: String }] }
I tried db.getCollection('test').updateMany({}, { $rename: { 'list_name.name_1': 'name_2' }})
But it's throwing an error: WriteError: cannot use the part (list_name of list_name.name_1) to traverse the element ({list_name: [ { name_1: "test" } ]})
$rename does not work if these fields are in array elements
Refer
To achieve, you need $unset and $set document by document. You can use bulkwrite also.
list_name is an array. Hence $rename didn't work.
When I search, I get this. You can refer the second answer if you have less number of docs.
Else, you need to use either bulk write or mongo dump options.

Mongoose update query - Mongoose/Mongodb

I have a collection called student, now I want to update the object value inside array based on condition. Can anyone help me to figure this logic please.
Student:
{
_id: "5996d10e0b992e5def651db4"
name: "Siva"
mark:[
{subject:"Tamil",mark:"50"},
{subject:"English",mark:"25"},
{subject:"Science",mark:"25"},
]
__v: 36
}
Expected Result:
I want to update only Tamil mark by checking the subject value...
You can update sub-array element or object by using positional operator $, in your example it should something like this:
Student.update(
{ "mark.subject": "Tamil" },
{ "$set": { "mark.$.mark": "60" } }
)
You can read more documentation here

How to query nested arrays in mongodb from command line

I have some data structured like this in a mongo collection:
{ "list" : [ { "update_time" : NumberLong(1426690563), "provider" : NumberLong(4) } ] }
What I would like to do is query for all of the entries where the list includes a provider value of 4.
If it helps, all of the list arrays contain only one element.
What I am trying right now is this:
db.collection.find(
{
list: {
provider: 4
}
}
)
This does not work though, and always returns an empty set
Use the dot notation i.e. concatenate the name of the field that contains the array, with a dot (.) and the name of the field in the embedded document and use that as your query:
db.collection.find({"list.provider": 4})
You can also use the $elemMatch operator to specify multiple criteria on an array of embedded documents such that at least one embedded document satisfies all the specified criteria:
db.collection.find({
list: {
$elemMatch: {
provider: 4
}
}
})

mongodb positional operator in the find part of update()

I'm trying to update a certain field in my mongodb collection 'users'
Example of a document:
{
_id: ObjectId("536d4d3307221f847fbbea49"),
groups: [
{
match_id: "dc3acf1b",
groupName: "World Cup, Group A",
score:[0,1]
},
{
match_id: "d4f14940",
groupName: "World Cup, Group A",
score:[2,1]
}],
name:"Foo Bar",
points:10
}
I'm trying to update only score fields that have a certain score..
here is what I want (position operator) :
db.users.update({'groups.match_id':i_match , 'groups.score':i_score},
{$inc:{points:1}});
Now I figure this would look for a user that has both those fields, but I want to look in the same groups object that had the first part of the query.
As in:
db.users.update({'groups.match_id':d4f14940 , 'groups.score':[2,1]},
{$inc:{points:1}});
should give the user +1 points
But:
db.users.update({'groups.match_id':dc3acf1b , 'groups.score':[2,1]},
{$inc:{points:1}});
Should not
You get my drift :)
Now I know from the positional operator that I should use the '$' sign, but I think that can only be used in the second paramater of the update() - the updating part..and not the finding part
note - The actual comparison of the score in this way (arrays) might not work..but that's not the issue here
What you want is the $elemMatch operator. This allows you to select array elements that require multiple fields to match a condition:
db.users.update(
{ "groups": {
"$elemMatch": {
"match_id": "d4f14940",
"score": [2,1]
}
}},
{ "$inc": { "points": 1 } }
)
So that allows you to match the document as the "groups" array contains an element that has both match_id and score that meet the conditions you supplied. If you change that match_id without altering the score, then the document does not match and the increment is not made to your points value.
So this has nothing to do with the positional $ operator in this case as you are not updating and array at a matched position, which is what that is for.