Updating a nested mongodb object fails - mongodb

I have this mongodb data i have stored in this way
db.orders.insert( { _id: ObjectId().str, name: "admin", status: "online",catalog : [
{
"objectid" : ObjectId().str,
"message" : "sold",
"status" : "open"
}
]})
and i am trying to update it in this manner db.orders.update({"_id":"5703b86df3d607cb5fa75ff3"},{$set: {"catalog.message": "added to cart"}})
and this is the error message i am getting
> db.orders.update({"_id":"5703b86df3d607cb5fa75ff3"},{$set: {"catalog.message": "added to cart"}})
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16837,
"errmsg" : "cannot use the part (catalog of catalog.message) to traverse the element ({catalog: [ { objectid: \"5703b86df3d607cb5fa75ff4\", message: \"sold\", status: \"open\" } ]})"
}
})
How can i update this record?.

According to MongoDB's Examples you should provide the index of the Object in the array which you want to update. Since you want to update the first object i.e. object in the array at index 0 use this :
db.orders.update(
{"_id":"5703b86df3d607cb5fa75ff3"},
{$set: {"catalog.0.message": "added to cart"}});

Related

How to update hours in data field in mongodb

I have set of mongo document, I need to convert/update the below values like ("workedDate" : ISODate("2020-07-01T00:00:00Z"))
"workedDate" : ISODate("2020-07-01T20:03:04Z"),
"workedDate" : ISODate("2020-07-01T19:59:07Z"),
"workedDate" : ISODate("2020-06-30T14:00:00Z"),
"workedDate" : ISODate("2020-07-01T19:49:29Z")
I have tried the below query:
db.timeentrys.update(
{ },
{
$set: {
workedDate:{$dateFromParts:{
year:{$year:"$workedDate"},
month:{$month:"$workedDate"},
day:{$dayOfMonth:"$workedDate"}
}}
}
}
)
Getting the below error :
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 52,
"errmsg" : "The dollar ($) prefixed field '$dateFromParts' in 'workedDate.$dateFromParts' is not valid for storage."
}
})
$dateFromParts is an aggregation expression. You can only use aggregation expressions in an update if you are using MongoDB 4.2, and provide a pipeline array as the second argument to update instead of an object.
Edit
In this use, just wrap the update object in [] to make it an array:
db.timeentrys.update(
{ },
[{$set: {
workedDate:{$dateFromParts:{
year:{$year:"$workedDate"},
month:{$month:"$workedDate"},
day:{$dayOfMonth:"$workedDate"}
}}
}}]
)

What are the efficient query for mongodb if value exist on array then don't update and return the error that id already exist

I have an entry stored on my collection like this:
{
"_id" : ObjectId("5d416c595f19962ff0680dbc"),
"data" : {
"a" : 6,
"b" : [
"5c35f04c4e92b8337885d9a6"
]
},
"image" : "123.jpg",
"hyperlinks" : "google.com",
"expirydate" : ISODate("2019-08-27T06:10:35.074Z"),
"createdate" : ISODate("2019-07-31T10:24:25.311Z"),
"lastmodified" : ISODate("2019-07-31T10:24:25.311Z"),
"__v" : 0
},
{
"_id" : ObjectId("5d416c595f19962ff0680dbd"),
"data" : {
"a" : 90,
"b" : [
"5c35f04c4e92b8337885d9a7"
]
},
"image" : "456.jpg",
"hyperlinks" : "google.com",
"expirydate" : ISODate("2019-08-27T06:10:35.074Z"),
"createdate" : ISODate("2019-07-31T10:24:25.311Z"),
"lastmodified" : ISODate("2019-07-31T10:24:25.311Z"),
"__v" : 0
}
I have to write the query for push userid on b array which is under data object and increment the a counter which is also under data object.
For that, I wrote the Code i.e
db.collection.updateOne({_id: ObjectId("5d416c595f19962ff0680dbd")},
{$inc: {'data.a': 1}, $push: {'data.b': '124sdff54f5s4fg5'}}
)
I also want to check that if that id exist on array then return the response that following id exist, so for that I wrote extra query which will check and if id exist then return the error response that following id exist,
My question is that any single query will do this? Like I don't want to write Two Queries for single task.
Any help is really appreciated for that
You can add one more check in the update query on "data.b". Following would be the query:
db.collection.updateOne(
{
_id: ObjectId("5d416c595f19962ff0680dbd"),
"data.b":{
$ne: "124sdff54f5s4fg5"
}
},
{
$inc: {'data.a': 1},
$push: {'data.b': '124sdff54f5s4fg5'}
}
)
For duplicate entry, you would get the following response:
{ "acknowledged" : true, "matchedCount" : 0, "modifiedCount" : 0 }
If matched count is 0, you can show the error that the id already exists.
You can use the operator $addToSet to check if the element already exits in the array.
db.collection.updateOne({_id: ObjectId("5d416c595f19962ff0680dbd")},
{$inc: {'data.a': 1}, $addToSet: {'data.b': '124sdff54f5s4fg5'}}
)

Update Field in Array of Objects MongoDb [duplicate]

This question already has answers here:
How do I update Array Elements matching criteria in a MongoDB document?
(2 answers)
Closed 4 years ago.
I have an object that looks like the following:
> db.delegate_list.find({"name": "delegateList"}).pretty()
{
"_id" : ObjectId("5becd1e0adeb2717c087cec5"),
"name" : "delegateList",
"delegates" : [
{
"address" : "tz1SUgyRB8T5jXgXAwS33pgRHAKrafsdkjhc",
"sync" : false
},
{
"address" : "tz1MecudVJnFZN5FSrriu8ULz2d6dDTR7KaM",
"sync" : false
}
]
}
I am trying to update the sync field for specific object in the array. So for example if I update the sync field for the object at index 0 or address tz1SUgyRB8T5jXgXAwS33pgRHAKrafsdkjhc by doing the following it yields:
> db.delegate_list.update({"name":"delegateList"}, {$set:{"delegates.0.sync": true}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.delegate_list.find({"name": "delegateList"}).pretty()
{
"_id" : ObjectId("5becd1e0adeb2717c087cec5"),
"name" : "delegateList",
"delegates" : [
{
"address" : "tz1SUgyRB8T5jXgXAwS33pgRHAKrafyg87Yc",
"sync" : true
},
{
"address" : "tz1MecudVJnFZN5FSrriu8ULz2d6dDTR7KaM",
"sync" : false
}
]
}
It works as expected, but if I perform the same update command to switch back sync:false, it gives me a malformed object, while deleting the rest of the array:
> db.delegate_list.update({"name":"delegateList"}, {$set:{"delegates.0.sync": false}})
WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
> db.delegate_list.find({"name": "delegateList"}).pretty()
{
"_id" : ObjectId("5becd1e0adeb2717c087cec5"),
"name" : "delegateList",
"delegates" : {
"address" : "tz1SUgyRB8T5jXgXAwS33pgRHAKrafyg87Yc",
"sync" : true,
"0" : {
"sync" : false
}
}
}
You can update specific array item, if item match your case using $ operator
db.delegate_list.update({"delegates.address":"tz1SUgyRB8T5jXgXAwS33pgRHAKrafyg87Yc"}, {$set:{"delegates.$.sync": false}})
It will update the sync filed which address is "tz1SUgyRB8T5jXgXAwS33pgRHAKrafyg87Yc"
only, and not going to add any extra field.

Mongo Db update failing while using $Set for a null valued field

I am trying to update an existing document which has a field with null value in it and I am getting the following error.
Document:
{
"_id" : ObjectId("582299f71e21dbf65027325e"),
"b" : "5555",
"f" : null
}
Query:
db.getCollection('temp').update({"b":"5555"},{"$set":{"f.1.b":1,"f.2.b":2}})
Error:
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16837,
"errmsg" : "cannot use the part (f of f.1.b) to traverse the element ({f: null})"
}
})
Anyone can tell me why it was not updating the value in the document.
Thank you.
Because there are no f.1.b and f.2.b object found to set
In this case you can try this
Prepare a proper object and try to set
Eg :
var temp = {
1 : {b: 1},
2: {b : 2}
}
db.getCollection('temp').update({"b":"5555"},{"$set":{f:temp}})

Update an item in an array that is in an array

I have a document in a mongodb collection like this :
{
sessions : [
{
issues : [
{
id : "6e184c73-2926-46e9-a6fd-357b55986a28",
text : "some text"
},
{
id : "588f4547-3169-4c39-ab94-8c77a02a1774",
text : "other text"
}
]
}
]
}
And I want to update the issue with the id 588f4547-3169-4c39-ab94-8c77a02a1774 in the first session.
The problem is that I only know that it's the first session and the issue id (NOT the index of the issue !)
So I try something like this :
db.mycollection.update({ "sessions.0.issues.id" : "588f4547-3169-4c39-ab94-8c77a02a1774"},
{ $set: { "sessions.0.issues.$.text" : "a new text" }})
But I got the following result :
WriteResult({
"nMatched" : 0,
"nUpserted" : 0,
"nModified" : 0,
"writeError" : {
"code" : 16837,
"errmsg" : "The positional operator did not find the match needed from the query. Unexpanded update: sessions.0.issues.$.text"
}
How can I do this ?
Thanks for help.
You have to use this (apparently equivalent) query:
db.mycollection.update({"sessions.0.issues": {$elemMatch: {id: <yourValue>}}}, {$set: {"sessions.0.issues.$.text": "newText"}})
Notice that your update expression was correct.
More information about $elemMatch.
Btw, MongoDB reference explicits that $ operator does not work "with queries that traverse nested arrays".
Important: $elemMatch only works with version 4 or more.