How to update Meteor array element inside a document - mongodb

I have a Meteor Mongo document as shown below
{
"_id" : "zFndWBZTvZPgSKXHP",
"activityId" : "aRDABihAYFoAW7jbC",
"activityTitle" : "Test Mongo Document",
"users" : [
{
"id" : "b1#gmail.com",
"type" : "free"
},
{
"id" : "JqKvymryNaCjjKrAR",
"type" : "free"
},
],
}
I want to update a specific array element's email with custom generated id using Meteor query something like the below.
for instance, I want to update the document
if 'users.id' == "b1#gmail.com" then update it to users.id = 'SomeIDXXX'
So updated document should looks like below.
{
"_id" : "zFndWBZTvZPgSKXHP",
"activityId" : "aRDABihAYFoAW7jbC",
"activityTitle" : "Test Mongo Document",
"users" : [
{
"id" : "SomeIDXXX",
"type" : "free"
},
{
"id" : "JqKvymryNaCjjKrAR",
"type" : "free"
},
],
}
I have tried the below but didnt work.
Divisions.update(
{ activityId: activityId, "users.id": emailId },
{ $set: { "users": { id: _id } } }
);
Can someone help me with the relevant Meteor query ? Thanks !

Your query is actually almost right except for a small part where we want to identify the element to be updated by its index.
Divisions.update({
"activityId": "aRDABihAYFoAW7jbC",
"users.id": "b1#gmail.com"
}, {
$set: {"users.$.id": "b2#gmail.com"}
})

You might need the arrayFilters option.
Divisions.update(
{ activityId: activityId },
{ $set: { "users.$[elem].id": "SomeIDXXX" } },
{ arrayFilters: [ { "elem.id": "b1#gmail.com" } ], multi: true }
);
https://docs.mongodb.com/manual/reference/operator/update/positional-filtered/

You need to use the $push operator instead of $set.
{ $push: { <field1>: <value1>, ... } }

Related

Need to convert Mongo string field to array of Object

I have a document like this
{
"_id" : ObjectId("6228cd8e72e74fa2a4bbd76c"),
"userId" : 8426,
"answer" : "https://cdn.upgrad.com/resumejyotiranjana.docx",
"updatedAt" : ISODate("2022-06-09T13:48:17.296Z"),
"questionIdentifier" : "resumeLink",
}
I need to convert answer into array of objects, The existing answer will become resumeLink properties and updatedAT will become dateUploaded in object.
{
"_id" : ObjectId("6228cd8e72e74fa2a4bbd76c"),
"userId" : 8426,
"answer" : [
{
"resumeLink":"https://cdn.upgrad.com/resume/asasjyotiranjana11.docx",
"dateUploaded": "2022-06-09T13:48:17.296Z",
"resumeId": "7fa1478d-478f-4869-9c4b-7ca8c0b9434g",
"source": "hiration"
}
],
"updatedAt" : ISODate("2022-06-09T13:48:17.296Z"),
"questionIdentifier" : "resumeLink",
}
Whats the quick way to achieve this with mongo query? thanks in advance
Use aggregation query as below.
You may need to add some fields in that.
const agg = [
{
'$match': {
'userId': 8426
}
}, {
'$group': {
'_id': '$userId',
'answers': {
'$addToSet': {
'recordId': '$_id',
'resumeLink': '$answer'
}
}
}
}
];
Below mongo query worked:
db.getCollection('userfeedback').updateMany(
{userId:8426, questionIdentifier:"resumeLink"},
[{
"$set": {
answer: [{
"resumeLink": "$answer",
"resumeId": UUID().hex().match(/^(.{8})(.{4})(.{4})(.{4})(.{12})$/).slice(1,6).join('-'),
"uploadSizeInByte": -1,
"source":"manual",
"dateUploaded": "$updatedAt"
}]
}
}]
)

MongoDB - Update an Key

I have been trying to update an Object for this collection. Below is the collection. Looking for Server 3.6 version.
Here The ask is Need to update the class name from "HISTORY" to " HISTORY_NEW". Need to do, for some students in the class. Need a query that will select all student records in student collection with "HISTORY" class in it and update them to "HISTORY_NEW ". I have around 30,000 records and not getting a bulk update method.
{
"_id" : ObjectId("611f90aa43f77a728879c395"),
"studentId" : "stu1",
"classes" : {
"History" : {
"TeacherName" : "T1",
"Marks" : [
{
"Internal": 15
}
]
},
"Geography" : {
"TeacherName" : "T2",
"Marks" : [
{
"Internal" : 20
}
]
}
},
"updateDate" : ISODate("2021-10-12T11:40:47.156Z")
}
This is the result I am expecting
{
"_id" : ObjectId("611f90aa43f77a728879c395"),
"studentId" : "stu1",
"classes" : {
"HISTORY_NEW" : {
"TeacherName" : "T1",
"Marks" : [
{
"Internal": 15
}
]
},
"Geography" : {
"TeacherName" : "T2",
"Marks" : [
{
"Internal" : 20
}
]
}
},
"updateDate" : ISODate("2021-10-12T11:40:47.156Z")
}
.Or is that even possible with the kind of collection above or going via code route?
So far this is what I have, without any success.
Get all students' Ids and then update the Class name. But that is also not working and don't think it is smart to update DB 30,000 times.
var studentIds =[];
db.studentSubject.find({"classes.History":{$exists:true}})
.forEach(function(u) { studentIds.push(u.studentId) })
studentIds.forEach(function(studentId) {
var result;
try {
result =db.studentSubject.updateOne(
{studentId:studentId},
{ $set : {"classes.History": "HISTORY_NEW",}},
{ upsert: false});
} catch (e) {
print(e);
}
});
From your scenario, you need $rename operator.
As discussed in the comment, you don't need to fetch each document to get studentId and then pass it to update each document. Just bulk update by checking the document has classes.History field.
db.collection.update({
"classes.History": {
$exists: true
}
},
{
$rename: {
"classes.History": "classes.HISTORY_NEW"
}
},
{
upsert: false,
multi: true
})
Sample Mongo Playground

MongoDB- Add new field from existing array

I am the beginner of the MongoDB
Here I mentioned my database schema
{
"_id" : ObjectId("5e72067973c1241068a13647"),
"client_id" : "1001",
"dependent" : [
{
"dependent_name" : "asdsa",
"dependent_id" : "DE100"
},
{
"dependent_name" : "fdggd",
"dependent_id" : "DE101"
}
]
}
I want to add new field based on client_id and dependent_id
Here I mentioned My query but cannot able to get my expected result
db.collection.update({"client_id" : "1001","dependent.dependent_id":"DE101"}, {"$push": {"reason":"expired"}})
I am Expected Result is
{
"_id" : ObjectId("5e72067973c1241068a13647"),
"client_id" : "1001",
"dependent" : [
{
"dependent_name" : "asdsa",
"dependent_id" : "DE100"
},
{
"dependent_name" : "fdggd",
"dependent_id" : "DE101",
"reason":"expired"
}
]
}
so anyone help me to solve this
db.collection.update({"client_id" : "1001","dependent.dependent_id":"DE101"},
{$set:
{"dependent.$.reason":"expired"}})
Try this it works for me using $
As i am also new to mongodb, as i tried, i can give you suggestion to update whole document or replace it.
both way i tried, and query is as below.
Update
db.updateColl.update({ 'dependent.dependent_id': 'DE101' },
{
$set: {
"dependent": [
{
"dependent_name": "asdsa",
"dependent_id": "DE100"
},
{
"dependent_name": "fdggd",
"dependent_id": "DE101",
"reason": "expired"
}
]
}
});
Replace
db.updateColl.replaceOne({ 'dependent.dependent_id': 'DE101' }, {
"dependent": [
{
"dependent_name": "asdsa",
"dependent_id": "DE100"
},
{
"dependent_name": "fdggd",
"dependent_id": "DE101",
"reason": "expired"
}
]
})
may be it can help you. if any suggestion regarding it wellcome.

Mongodb: Finding and updating object property from array

I have a collection with multiple documents which follow this structure:
{
"_id" : {
"oid" : XXX
},
"name" : "Name",
"videos" [
{
"id" : 1,
"thumbnail" : "thumbnail.jpg",
"name" : "Name here"
},
{
"id" : 2,
"thumbnail" : "thumbnail.jpg",
"name" : "Name here"
},
{
"id" : 3,
"thumbnail" : "thumbnail.jpg",
"name" : "Name here"
}
]
}
I want to find and update the a thumbnail of a video, of which I only know the id, but not which document it is in.
This is what I've tried so far, but it's not working properly. All the examples I found relied on knowing the document id, and the array position of the object to update. I also found that doing a query like this found the document okay, but set the whole document as the new thumbnail!
db.collection(COLLECTION-NAME, function(err, collection){
collection.update(
{ 'videos.id' : 2 },
{ $set: { thumbnail: "newThumbnail.jpg" } },
function(err, result){
if (!err){
console.log('saved', result)
} else {
console.log('error', err);
}
}
);
});
Use the $ positional operator to update the value of the thumbnail field within the embedded document having the id of 2:
db.collection.update(
{ "videos.id": 2 },
{ "$set": { "videos.$.thumbnail" : "newThumbnail.jpg" } }
)

Modify a document inside an array in MongoDB

Past answers (from mid 2013 and before) don't seem to work and links to the documentation are all out of date.
Example user object:
{
"name": "Joe Bloggs",
"email": "joebloggs#example.com",
"workstations" : [
{ "number" : "10001",
"nickname" : "home" },
{ "number" : "10002",
"nickname" : "work" },
{ "number" : "10003",
"nickname" : "vacation" }
]
}
How can I modify the nickname of a workstation?
I tried using $set, workstations.$ and workstations.nickname but none gave the desired results.
Short answer, you have to use array index. For example, you want to update the nickname of 10002: {$set:{"workstations.1.nickname":"newnickname"}}
Here is the complete example:
> db.test.update({"_id" : ObjectId("5332b7cf4761549fb7e1e72f")},{$set:{"workstations.1.nickname":"newnickname"}})
> db.test.findOne()
{
"_id" : ObjectId("5332b7cf4761549fb7e1e72f"),
"email" : "joebloggs#example.com",
"name" : "Joe Bloggs",
"workstations" : [
{
"number" : "10001",
"nickname" : "home"
},
{
"nickname" : "newnickname",
"number" : "10002"
},
{
"number" : "10003",
"nickname" : "vacation"
}
]
}
>
If you don't know the index (position of the workstations), you can update the doc using $elemMatch:
>db.test.update(
{
"email": "joebloggs#example.com",
"workstations": { "$elemMatch" { "number" : "10002" } }
},
{
"$set": { "workstations.$.nickname": "newnickname2" }
}
)
>
#naimdjon's answer would work. To generalize, you could use the $elemMatch operator in combination with the $ positional operator to update one element in the array using below query:
db.test.update({
// Find the document where name="Joe Bloggs" and the element in the workstations array where number = "10002"
"name": "Joe Bloggs",
"workstations":{$elemMatch:{"number":"10002"}}
},
{
// Update the nickname in the element matched
$set:{"workstations.$.nickname":"newnickname"}
})
Note: $elemMatch is only required if you need to match more than one component in the array. If you are going to match on just the number, you could use "workstations.number":"10002"
As long as you know "which" entry you wish to update then the positional $ operator can be of help. But you need to update your query form:
db.collection.update(
{
"email": "joebloggs#example.com",
"workstations": { "$elemMatch" { "nickname" : "work" } }
},
{
"$set": { "workstations.$.nickname": "new name" }
}
)
So that is the general form. What you need to do here is "match" something in the array in order to get a "position" to use for the update.
Alternately, where you know the position, then you can just "specify" the position with "dot notation":
db.collection.update(
{
"email": "joebloggs#example.com",
},
{
"$set": { "workstations.1.nickname": "new name" }
}
)
Which updates the second element in the array, and does not need the "matching" part in the query.