I want to set a field to a value of a nested field
given
{
"_id":"myId",
"data":{
"id":"asdfasdfasdf",
"text":"Wonderful text"
}
}
expected
{
"_id":"myId",
"messageId":"asdfasdfasdf",
"data":{
"id":"asdfasdfasdf",
"text":"Wonderful text"
}
}
Is there a possibility to do something like this?
db.myCollection.updateMany({},{ $set: {"messageId": "$data.id"} },false,true)
I am using MongoCompass -> _MongoSH
Yes, it's possible doing this using pipelined updates, added at version 4.2.
This is how you use it:
db.collection.updateMany(
{},
[
{
$set: {
"message": "$data.id"
}
}
])
Mongo Playground
For lesser Mongo versions you have to read the document first and then use the values for the update.
Related
i need to update the all user who have the rol user and change the nickName to lowercase, i try with this code
const users = await userModel.updateMany({ rol:'user' },
{
$set:{
nickName: {
$toLower : "$nickName"
}
}
});
but is not working
In the future, please describe in what way your approach is not working. I went ahead and copied your example into this playground example and saw that your current approach resulted in the document being modified to include this field:
"nickName": {
"$toLower": "$nickName"
}
The problem here is that you are attempting to use the (aggregation) $set stage in your update (so that you can reference the existing $nickName field), but the update is using the $set (non-aggregation) modifier. If you wrap your second argument in square brackets (telling the database that you want to use an aggregation) then it should do what you want:
db.collection.update({
rol: "user"
},
[
{
$set: {
nickName: {
$toLower: "$nickName"
}
}
}
])
Playground demonstration here
I am new to mongodb, I am learning from some Udemy courses and I want to know how I can update a document existing field without overwriting it.
I have the following collection with these documents:
enter image description here
I want to add new warehouses in the "item":"drafts" within the stock field.
What I am trying is:
enter image description here
And giving the output it seems that is working, but when I do again db.matrices.find(), what I get is the exactly same output that in the first image.
How can I update it? I have tried also the update method, but does not do what I want to do.
Thanks!
PD: I am using linux mint, with mongo v5.0.3, and mongosh v1.1.1
You are using the aggregate pipeline, this does not update the document in the DB, it just retrieves the result. starting in Mongo version 4.2+ you can now use an aggregation pipeline ( with some limitations ) to update a document, like so:
db.collection.updateOne({
item: "drafts"
},
[
{
$set: {
stock: {
$concatArrays: [
"$stock",
[
{
"warehouse": "A",
qty: 20
}
]
]
}
}
}
])
Mongo Playground
I will just say that this specific update is very simple, there is no need to use an aggregation pipeline for it. a simple use of the $push operator in the update field will suffice in a "normal" update:
db.collection.updateOne({
item: "drafts"
},
{
$push: {
stock: {
"warehouse": "A",
qty: 20
}
}
})
Mongo Playground
I have a mongoDB (4.4.8) collection where I want to change the value of some field based on its previous value. For example, I want to convert all strings to uppercase.
For this, I use the following query:
db.collection.updateMany(
{ field: { $regex: "[a-z]+"}},
{ $set: { field: { $toUpper: "$field" } } }
)
when executing the query, it gives me the following error:
MongoError: The dollar ($) prefixed field '$toUpper' in 'field.$toUpper' is not valid for storage
The same occurs if I use similar operations such as $concat (with an array parameter) to append something to the field.
When I look up similar questions, it all uses update and tells me to use updateMany instead, or it says that it only works in mongoDB >= 4.2. However, I have both of these things.
If I am correct, you are able to use aggregation syntax (among which $toUpper) in conjunction with $set inside updateMany queries for these newer versions of mongoDB.
Does anyone know what I'm doing wrong here?
As in the comments of J.F. and turivishal, I managed to solve this by changing it into the following:
db.collection.updateMany(
{ field: { $regex: "[a-z]+"}},
[ { $set: { field: { $toUpper: "$field" } } } ]
)
I have my collection like this:
{
"_id" : "ID1234",
"read_object" : "sss-ssss",
"expireAt" : ISODate("2020-04-30T22:00:00.000Z")
}
In case he encounters the same ID, I would like to update the read_object field, otherwise create a new document.
I tried to do it like this:
db.collection.update(
{ _id: "ID1234" },
{
$set: { read_object: { $concat: ["$read_object", "test"] } },
},
{ upsert: true }
)
but I get an error every time:
The dollar ($) prefixed field '$concat' in 'read_object.$concat' is not valid for storage.
If I add square brackets before $set, like this:
db.collection.update(
{ _id: "1b1b871493-14a0-4d21-bd74-086442df953c-2020-02" },
[{
$set: { read_object: { $concat: ["$read_object", "test"] } },
}],
{ upsert: true }
)
I get this error:
The dollar ($) prefixed field '$concat' in 'read_object.$concat' is not valid for storage.
Where do I have a mistake?
$concat is an aggregation operator, meaning you can't use it while using the basic update syntax as you can only use update operators on it.
With that said Mongo version 4.2 introduces pipeline updates, which is basically what you're trying to do with the square brackets.
Assuming you are using Mongo version 4.2 heres a working example:
db.test1.update({_id: "ID1234"}, [
{$set: {"read_object": {$concat: [{$ifNull: ["$read_object", ""]}, "test"]}}}
], {upsert: true});
Basically we just need to "replace" read_object if document does not exist as it is undefined in that case.
If you are using Mongo version that's smaller than 4.2 then unfortunately there is no way to do what you want in one operation, you'll have to first read the document and then adjust accordingly.
My document in MongoDB is like this:
{
"data":{
"groupName":"sample",
"users": [
{
"_id":new ObjectId(),
"mobNum":"29857903289",
"isAdmin":"true"
},
{
"_id":new ObjectId(),
"mobNum":"87532480923",
"isAdmin":"false"
},
]
}
}
users is an array of embedded-ducuments in groupusers collection. When I try to query the embedded sub field like this
db.groupusers.find( { "users.$.mobNum": "29857903289" } ), it returns me no response.
Problem is in querying the embedded sub field. I'm new to use MongoDB. Don't know how to query the embedded array of sub field. Not sure what to do. Any help is appreciated.
Here use this
db.getCollection('YOUR_COLLECTION_HERE').find({
"data.users": {
"$elemMatch": {
"mobNum": "29857903289"
}
}
}})