MongoDB - Update/Insert the Array of object - node.js

I've one collection i.e 'comments', Which contain two fields. Like below -
Comments -
{
_id: 'unique_string',
dataVar: [{
name: {
type: string
},
value: {
type: string
}
}]
}
You can assume the collection data is like below -
[
_id: 'xxxxxx',
user: 'robin',
dataVar: [{
name: 'abc',
value: 123
}, {
name: 'bcd',
value: 12345
}]
]
Now the problem is - (I'm using mongoose in nodeJS application)
- How to update and insert the data in 'dataVar' ?
- If data is no available then new document should be created.
Case 1.
If user send the post data like
{
_id: 'xxxxxx',
user: 'robin',
dataVar: [{name: 'abc', value: 12345}]
}
then after performing query, the above document (whose _id is 'xxxxxx') should be update like below -
{
_id: 'xxxxxx',
user: 'robin',
dataVar: [
{name: 'abc', value: 12345},
{name: 'bcd', value: 12345}
]
}
Case 2.
If data is not present then new document should be created.

To update record in mongodb, you can use like
comments.findOneAndUpdate({ _id: 'xxxxxx' }, { $push: { dataVar: {$each: [{name: 'abc', value: 123}, {name: 'def', value: 456}] } } })
You can use {upsert: true} option for creating field in collection if not exist.
For updating record, you have to use sub-schema inside your main schema. So that _id field is created in every object of array. So you can uniquely identify object to update inside array.
comments.findOneAndUpdate({ "dataVar._id": 'xxxxxx' }, { $set: { name: 'xyz', value: 789 } })
In this way, you can update object, which is inside array.
If you don't want to use _id, you have at-least one field which contains unique values. So that you can findOneAndUpdate that specific object inside array.

Related

Mongoose populate query and unwrap the objects to obtain an array of strings

I have the following query with mongoose:
const user = await this.userModule.findById(id).populate('roles', 'label -_id');
The output will look like this:
{
_id: new ObjectId("61e2bc757644758d31578c7d"),
email: 'hehehe#hehe.com',
roles: [ { label: 'basic' }, { label: 'admin' } ]
}
My question is if there is a way to achieve something like this:
{
_id: new ObjectId("61e2bc757644758d31578c7d"),
email: 'hehehe#hehe.com',
roles: [ 'basic', 'admin']
}
I want to get the value of each label property and add it to the roles array instead of adding an object like {label: basic}

How to filter collection based on input array in mongoDB [duplicate]

I have following documents
{
name: 'John',
Address :'street 1 '
},
{
name: 'Jane',
Address :'street 2 '
},
{
name: 'Smith',
Address :'street 3 '
}
I want to search the multiple document with different vales in mongo aggregation pipeline.
That means name =('John','Smith'). I'm expecting result is
{
name: 'John',
Address :'street 1 '
},
{
name: 'Smith',
Address :'street 3 '
}
My code is
db.articles.aggregate($match: { $or: [{ name: 'John' }, { name: 'Smith' }]);
This is giving an empty value.is it possible to get document like this way?
You need to use operator the $in
The $in operator selects the documents where the value of a field
equals any value in the specified array.
[{
$match: {
name: {
$in: ['John', 'Smith']
}
}
}]
Reference: MongoDB Docs: $in

Why I could still assign ObjectId type value to an Array of String in Typescript?

I'm using node with typescript, and mongoose for database.
I have this code that takes user model from database (using mongoose) by user id, then takes the user roles attribute. The roles attribute contains array of object. Inside each object (roles) contains _id
// Check User Roles
const user = await this.userModel.findById(req.identitas.user._id)
const userRoles: Array<string> = []
for (let index in user.roles) {
userRoles.push((user.roles[index]._id))
}
When i try to check the type of what's pushed to userRoles
console.log(typeof(userRoles[0]))
It says that it has object type variable.
I then decided to try
userRoles.push({ dummy: "dummy" })
and it wouldn't let me do that. So I know for sure that the type declaration in
const userRoles: Array<sring> = []
is working properly. But, at the same time, it isn't. When I try to push _id to userRoles, it still somehow allows me to do that.
This is a problem because I'm using this userRoles array of string to compare it with another string value, using
userRoles.includes("some-string-here")
Why and how did this thing could happen?
*This is what user variable contains:
{
roles: [
{
_id: 5f93fdc**********36,
name: 'Karyawan Cabang Neutron',
...
__v: 2,
policies: [],
organization: 5f8fe9a62*****000082e3fef
}
],
units: [
{
_id: 5fc1f9******00081b2897,
name: 'Neutron Yogyakarta 2',
code: '102',
organization: 5f8fe****42a2000kj13fef,
createdAt: 2020-11-28T07:18:09.628Z,
updatedAt: 2020-11-28T07:18:09.628Z,
__v: 0
}
],
organizations: [
{
_id: 5f8c6b*****b75jg008d4a156,
...
__v: 34,
code: 'NEO',
logo: [Object],
content: [Array],
object: [Object],
config: [Array]
}
],
_id: 5fdad1a25e9f78****c42,
email: 'email#example.com',
username: 'EmiliaBestGirl',
...
isEmailVerified: true,
identities: [],
createdAt: 2020-12-17T03:33:54.484Z,
updatedAt: 2020-12-22T08:12:24.019Z,
__v: 3,
...
}

How can I update 2 or more unique documents in mongoose db

I have 3 unique documents in mydb, I want to update each document using there unique keys that are generated randomly.
I tried updateMany() and update({multi:true}). Using upadteMany() we can update the document that matches the query. Is there any way that I can solve this problem?
Thanks in advance.
If I have the following documents:
doc1 : {
_id: 1,
name: 'John Smith',
age: 20
}
doc2 : {
_id: 2,
name: 'Jane Smith',
age: 22
}
I want the client to be able to pass me both docs in the same request for update. In this case maybe add an address to both docs.
Is there a way the I can send one update statement to mongo such that it updates both of the documents with the name values?
the answer you provided is good. but i modified that code and it looks like
_id: { $in: [req.params.noteId,req.params.noteId,req.params.noteId]}
}
Note.updateMany(query,
{$set:{
lname: req.body.lname || "Untitled Note",
age: req.body.age
}}
, { new: true }
)
this code is not working
From the below code you can solve your problem .
//consider the following object to update
doc1 : {
_id: 1,
name: 'John Smith',
age: 20
}
doc2 : {
_id: 2,
name: 'Jane Smith',
age: 22
}
The below code will change the name of both the docs to manjesha
var criteria = {
_id : { $in : [ "1" , "2"] }
}
userModel.update(criteria , { name: "manjesha" }, { multi: true },function(err , found){
if(err){
res.send(err);
}else{
res.send(found);
}
});
// $in -The $in operator selects the documents where the value of a field equals any value in the specified array.
This will work perfect on your problem .

How to include documents as subdocuments in MongoDB?

I have a basic user collection that consists of document like so:
{
user: 3949fj9fn9rjhfne93,
name: "Jerry",
country: 'au',
friends: ['20fn39r4hf93', 'g9en3irhr934', '4i5henifuw92']
}
Each of those friends also has a document the same, along with there being a large collection of countries that can be queried via the country code.
{
code: 'AU',
name: 'Australia'
}, {
code: 'NZ',
name: 'New Zealand'
}
My question is, how would I include the full document for each of those array items within the result, like so:
{
user: 3949fj9fn9rjhfne93,
name: "Jerry",
country: {
code: 'AU',
name: 'Australia'
},
friends: [{
user: 20fn39r4hf93,
name: "Bob",
friends: ['2049429fr', 'djwij393i4']
}, {
user: g9en3irhr934,
name: "Foo",
friends: []
}, {
user: 4i5henifuw92,
name: "Bar",
friends: ['2049429fr']
}]
}
I am using Mongoose in my application, and I understand that this could be done by using a simple for loop and pushing the results to the user object and then returning it in node with res.json(user), although what if the user had hundreds (or even thousands) of friends? The request would be huge. I also need to do this in multiple places within my API.
Is there a more efficient way to achieve this?

Resources