How to populate updated document by id in schema array - node.js

I am trying to learn and implement few operations which are newer for me. I have a child schema details which I am pushing in a parent schema array. Everything is going fine. But when it comes to front-end, concern about few things.
As per someone's advice ,I came to know we must store _id to another schema . And if we update details of that _id, it will get reflected in every schema docs where it has been stored.
Now I am login through parent schema and I want to see the entire details of those array _id as I need to show lists in front-end. Right now I can only see ids. I want to populate array of entire object of those ids.
I can populate data but I need to use a different API Url to show list. I do not want that . I know if I change ObjectId to Mixed, I can see whole object. But problem is that it will not show updated data. So I am pushing by ObjectId users:[ {type: mongoose.Schema.Types.ObjectId, ref: 'Userr'}]
So how will I populated updated users aray data on my main schema array without creating new route api ??
Child schema:-
{
"_id": "5d034653ff1e426fb0e3fca1",
"firstName": "xyz",
"lastName": "fg",
"__v": 0
}
Main schema response details :-
{
"admins": {
"users": [
"5d034653ff1e426fb0e3fca1" //<========= what i am getting
],
"email": "1cf1eede89#himail.online",
"password": "$2a$10$vHyGxX9P.t0/ybKcmIzkc.ZCX18oHaVnvTgJIWA2gTNzJ3TCdXS4a",
},
"_id": "5d0339d5b4b28b6ddff06802",
"companyID": "497399",
"__v": 0
}
I want to show result like this :
{
"admins": {
"users": [
"5d034653ff1e426fb0e3fca1",
"firstName" : "xyz",
"lastName" :"fg"
],
"email": "1cf1eede89#himail.online",
"password": "$2a$10$vHyGxX9P.t0/ybKcmIzkc.ZCX18oHaVnvTgJIWA2gTNzJ3TCdXS4a",
},
"_id": "5d0339d5b4b28b6ddff06802",
"companyID": "497399",
"__v": 0
}
Function for registering user :-
if(req.userData.role2 === 'admin') {
console.log("saving successful");
res.send(doc);
Admin.findOneAndUpdate({ _id: req.userData.userId }, { $push: { 'admins.users': userr._id } }, { new: true })
.populate('admins.users')
.exec(function(error, res){
if (error) {
console.log(error);
}else {
console.log(res.admins.users+ "populated")
}
});
}
This is showing me list of populate data but how can I show it in array object
I need to show the updated object of child schema. So that I can use in front-end for listing whatever details I want

Related

How can I get data from two collection in one Get request using mongoDB and node js

Node js js with MongoDB Get Request
My 1st collection registers contains user details.
My 2nd collection plans contains plan details.
I get my plan collection data with req.body._id
my get request code
userPlanGetControl: async (req, res) => {
try {
await plans.findOne({_id:req.body._id}).populate("registers").exec((err,docs)=>{
if(err) return handleError(err);
res.send(docs);
});
} catch (error) {
res.send(error);
}
},
my postman response
{
"_id": "620f99c6f323f62d4c3c8f9b",
"User": "620e12610449b7a382aa0266",
"PlaneName": "Gold",
"planDuration": "6 months",
"PlaneAmount": 199,
"StartDate": "18-02-2022",
"EndDate": "18-08-2022",
"planStatus": "Active",
"__v": 0
}
but I nee This type of Object
{
"_id": "620f99c6f323f62d4c3c8f9b",
"User": {
"_id": "620e12610449b7a382aa0266",
"username": "mariSelvan",
"email": "mari1226#gmail.com",
"mobile": 917708472804,
"todayDate": "2022-02-17T09:16:17.000Z",
"__v": 0
},
"PlaneName": "Gold",
"planDuration": "6 months",
"PlaneAmount": 199,
"StartDate": "18-02-2022",
"EndDate": "18-08-2022",
"planStatus": "Active"
}
I believe if you want to use .populate("registers") you also need to have your User in your schema be something like this :
User: { type: Schema.Types.ObjectId, ref: 'registers' }
I assume the ref is registers, if not then it would be whatever Model name you chose for the schema you want that info in User to come from. (edit: you would also need to change the actual call to populate to be .populate('User'); the argument should be the name of the field you want to replace)

Mongoose query to check array contains element or not in mongoose query

i have records like this..
{
"photo": "default.jpg",
"roles": [
{
"_id": "5f44d77be830263684eb7914",
"name": "Test",
"__v": 0
}
],
"_id": "5f44d2f4ff04993b40684bf9",
"name": "Test User",
"email": "test#gmail.com",
"id": "5f44d2f4ff04993b40684bf9"
}
i want to weather the role user trying to delete is in use or not. for this i have write a query but it always return an empty array.
const check = await User.find({roles: {$elemMatch: {_id: req.params.id}}});
these are the queries i checked in compass but it always an array
{"roles._id":"5f44d77be830263684eb7914"}
{roles: $elemMatch: {_id: "5f44d77be830263684eb7914"}}
my User document hass roles field something like this.
roles:[
{
type:mongoose.Schema.Types.ObjectId,
ref:"Roles",
validate: {
validator: async function(v) {
return await Roles.findById(v, (err, rec) => rec !== null)
},
message: 'Invalid Object ID'
},
required:true
}
],
IS there any way to enforce integrity constraint like if user tries to delete records which have dependencies on other records then we should not allow user to delete this record.

How to get information from all collection, but get only item of array

I'm using MongoDB with NodeJS, and I keep my data in a collection called "posts", in this way
{
"_id": "5ca0ff61f247dc29b8331af9",
"tipo": "First Mongo Post",
"user": {
"_id": "5ca01d2c56a2d9165c848f4f",
"nombre": "User1",
"email": "luis#gmail.com",
"permission": "Administrador",
"__v": 0
},
"rates": [
{
"user": "5ca01d2c56a2d9165c848f4f",
"votation": 1
},
{
"user": "5ca021b03904f70cf823b6e6",
"votation": -1
}
],
"__v": 0
}
I would like to think that the way that I save my data its correctly, whatever, I want to get all the information from my collection called "posts", but the array called rates, I only want to get the object that the user its the same like the user that make the call to the get method.
For example, If I call my get method, and I send the user ID (5ca01d2c56a2d9165c848f4f), I want to return all posts collection but in the the rates array of each one I only want to have the object that has the same ID compared by the ID that I sent in the get method, for example:
{
"_id": "5ca0ff61f247dc29b8331af9",
"tipo": "First Mongo Post",
"user": {
"_id": "5ca01d2c56a2d9165c848f4f",
"nombre": "User1",
"email": "luis#gmail.com",
"permission": "Administrador",
"__v": 0
},
"rates": [
{
"user": "5ca01d2c56a2d9165c848f4f",
"votation": 1
}
],
"__v": 0
}
To be honest, I don't know how can I do it, so i hope that you can help me or explain me how can I do it, please.
Regards, I'm new using this technologies
You can store Rate and Post objects separately, so you can create a new collection called rates to keep Rates separately from Posts collection. In the Rate collection you can store the postId, userId and votation value
const mongoose = require('mongoose');
const RateSchema = new mongoose.Schema({
userId: {
type: String
},
postId: {
type: String
},
votation: {
type: Number,
}
);
module.exports = mongoose.model('Rate', RateSchema);
After that you can create a function to get the rates that is related to userId and postId like
const Rate = require('../models/Rate');
function getRatesByUserIdandPostId(userId, postId) {
return Rate.find({userId, postId});
};
This way you don't need to search in a for loop for which rate is relate to that user, function will do it for you. Also it is faster because you don't get all the rates that is related to one specific post.

Adding fields to a nested document in mongoDB using Node js mongoDB driver

I wanted to know how to write a update for mongoDB using the Node js driver with the requirement as below
My document in a collection is as such
{
"_id": {
"$oid": "5a4e098e734d1d089c5a7473"
},
"username": "guest",
"password": "guest",
"categories": {
"movie": [
"Minions",
]
}
}
Now i want to add a new field in categories named games with an array as its value for a particular username
i wrote the query as below but it didn't work
db.collection('userdata').aggregate([ { '$match': { "username": "guest" } },{ '$addFields ': { "catagories.games" : [] }}],function(err, docs) {
assert.equal(null, err);
console.log(docs);
});
I want to know where am i going wrong or how to solve this issue
u can use update feature of mongodb
db.userdata.update(
{ "username": "guest" },
$set:{
"catagories.games" : []
},
{ upsert: true }
)
upsert true means if not exist,then insert
source-https://docs.mongodb.com/manual/reference/method/db.collection.update/

nested subdocument update in mongodb

{
"_id": "581dc52e2c26be354164d528",
"name": "vipin",
"__v": 0,
"post": [
{
"like": "today",
"_id": "581dc52e2c26be354164d529",
"comment": [
{
"date": "today",
"username": "vipin",
"_id": "581dc52e2c26be354164d52a",
"detail": [
{
"time": "now",
"day": "saturday",
"_id": "581dc52e2c26be354164d52b"
}
]
}
]
}
]
},
i have a nested subdocument.i want to update comment .date.but i cant do this .i want to nested subdocument update but query is not work.
Test.update({"_id":"581dc52e2c26be354164d528","post._id":"581dc52e2c26be354164d529","comment._id":"581dc52e2c26be354164d52a" },{
"$set":{
"post.$.comment.0.date.0":"tommorow"
}
},function(err,data){
if(data){
res.json(data)
};
if(err){
res.json(err)
}
})
}
my query is now worked .plzz anybody suggest me .
mongodb don't support positional operator matching nested arrays. check this issue it's still in open status:
https://jira.mongodb.org/browse/SERVER-831
workaround : use aggregation and fetch required subdocument make modifications and update subdocument using update query.
Okkk.we can update our nested subdocument in mongodb.this is our schema.
var Post = new mongoose.Schema({
name:String,
post:[{
like:String,
comment:[{
date:String,
username:String,
detail:{
time:String,
day:String
}
}]
}]
})
Now we can update our choosed field in mongoDb.if your document contains more than array of field like post,comment than it can be poor .but we can use many objects.like ......than we have no problem on updating.
post:[{
like:String,
comment:{
date:String,
username:String,
detail:{
time:String,
day:String,
address:{
street:String,
house:String
}
}
}
}]
})
so we have solution of first Schema is like this.our mongoDb query is working properly .so check this...
for first schema.if we have take more than one array in subdocument.
Test.update({"post._id":"58206a6aa7b5b99e32b7eb58"},
{$set:{
"post.$.comment.0.detail.time":"aajtk"}},
for second schema .if we have take more than objects.
db.tests.update({"post._id":ObjectId("58204e89cfee37f023a567bd")},{$set:{"post.$.comment.detail.time":"News"}})

Resources