Response output not showing entire information present in mongoose schema nodejs - node.js

I have designed a Mongoose schema like this :
const metricsSchema = mongoose.Schema({
_id : mongoose.Schema.Types.ObjectId,
level : String,
details: {
demo: String,
full: String
}
});
Also, I have handled the response as such :
router.post('/',(req, res, next)=>{
const metrics = new Metrics({
_id : new mongoose.Types.ObjectId(),
level : req.body.level,
details:{
demo: req.body.demo,
full: req.body.full
}
});
res.status(201).json({
metrics: metrics
})
});
However, when I use Postman to post JSON data like this :
{
"level" :"schema" ,
"details":{
"demo" : "2465",
"full" : "1211234"
}
}
I get output like this :
{
"metrics": {
"_id": "5e09c156b0ce8a4a54a3ecca",
"level": "schema"
}
}
I do not get the rest of the output : demo and full in the response json. I wish to get the output like this :
{
"metrics": {
"_id": "5e09c156b0ce8a4a54a3ecca",
"level": "schema"
"details": {
"demo": "2465",
"full": "1211234"
}
}
}
Update: I found one solution in which the Mongoose schema was divided into two parts :
const detailsSchema = mongoose.Schema({
_id : mongoose.Schema.Types.ObjectId,
demo: String,
full: String
});
mongoose.model('Details',detailsSchema );
const metricsSchema = mongoose.Schema({
_id : mongoose.Schema.Types.ObjectId,
level : String,
details: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Details'
}
});
However, this did not work as well.

You have to change the code as below:
router.post('/',(req, res, next)=>{
const metrics = new Metrics({
_id : new mongoose.Types.ObjectId(),
level : req.body.level,
details:{
demo: req.body.details.demo, <----- see the change here
full: req.body.details.full
}
});
res.status(201).json({
metrics: metrics
})
});

Related

Use arrayFilters in order to update a property of an object in nested array of objects, with Mongoose

I have a collection in MongoDb that has documents "flights" which contain a field array of objects. I want to update one property of one object at a time. In order to do so, I have to use two filters: One in order to select the document that I want to update, and a second one to select the object in the array.
I am using arrayFilters with Mongoose as follows:
This is my Flight shema
const mongoose = require('mongoose')
const Schema = mongoose.Schema
const flightSchema = new Schema({
flightName :{ type : String, required :true},
sits : {type : Array, required : true}, //[{n:1, d:f, s:f}]
origin : {type: String, required : true},
destination : {type : String, required: true},
departure : {type : Date, required : true},
arrival : {type : Date, required : true}
})
module.exports = mongoose.model('Flight', flightSchema)
// Models/Flight.js
{
flightName: a164651,
origin: Monterrey,
detination: Cancun,
sits: [{
sitNumber: 1,
isAvailable: true,
isSuspended: false
}, {
sitNumber: 2,
isAvailable: true,
isSuspended: false
}]
}
Lets imagine that I want to update the property IsSuspended from false to true in the object with sitNumber : 2.
//Controllers dashboard.js
blockSit : async (req, res) => {
try {
const flight = req.body.flightName
const sit = req.body.sitToBlock //sit es 2
const updateSit = await Flight.updateOne(
{ "flightName": flight},
{ "$set" : {"sits.$[si].isSuspended": true} },
{ "arrayFilters": [{ "si.sitNumber": sit} ]}
)
console.log(updateSit)
} catch (error) {
console.log(error)
}
}
As far as I can see my sintaxis is correct. However I keep receiving the following error message:
Error: Could not find path "sits.0.sitNumber" in schema
I do not have to use arrayfilters necesarily. I am open to try any other solution that allows me to update a property in a nested array of objects with mongoose.
It looks like your sits field is array of sub-documents but there is not a schema to describe the fields. Try defining the schema.
const sitSchema = new Schema({
sitNumber: Number,
isAvailable: Boolean,
isSuspended: Boolean,
// etc
});
// in the flight schema
sits: [sitSchema],
This is how I solved:
First I needed to use the method findOneandUpdate in Mongoose.
Also, I added to arrayFilters the property new and set it to true.
blockSit : async (req, res) =>{
try {
const flight = req.body.flightName
console.log(flight)
const sit = req.body.sit
console.log(sit)
const updateSit = await Flight.findOneAndUpdate(
{"flightName" : flight},
{ "$set" : {"sits.$[si].isSuspended" : true, "sits.$[si].isAvailable": false} },
{"arrayFilters" :[ { "si.sitNumber" :sit} ], new : true}
)
res.send(updateSit)
}
catch (error) {
console.log(error)
}
},

MongoError: Cannot apply $addToSet to non-array field. Field named 'trackTime' has non-array type string

Here i'm trying to update with the userid, trackTime fields. Evertime userid and trackTime will be different so i'm using $addToSetbut here i'm facing an error
like this i'm passing the data in postman:-
{
"courseId":"61001184afeacb22ac1668e0",
"userId":"60f6fe96a1a44a1fb4a59573",
"trackingTime":"4"
}
this is the schema:-
usersEnrolled : [{
iscourseenrolled : { type:Boolean, default: false },
userId: {type: String },
trackTime: {type:String}
}],
code:-
const updatedTrackTime = await Courses.updateOne({ "_id" : req.body.courseId},{
$addToSet:{
"usersEnrolled.0.userId" : req.body.userId,
"usersEnrolled.0.trackTime": req.body.trackingTime
}})
The reason for that error is probably because you didn't specify the array field (Actually you didn't specify any field at all). Try to add your usersEnrolled field like this:
const updatedTrackTime = await Courses.updateOne({ "_id" : req.body.courseId},{
$addToSet:{
usersEnrolled: {
"usersEnrolled.0.userId" : req.body.userId,
"usersEnrolled.0.trackTime": req.body.trackingTime
}
}});
To get more details on $addToSet use MongoDB Manual
https://docs.mongodb.com/manual/reference/operator/update/addToSet/
I just changed in to these and it worked for me
const updatedTrackTime = await Courses.updateOne({ "_id" : req.body.courseId},{ $addToSet:{
usersEnrolled : {
userId : req.body.userId,
trackTime: req.body.trackingTime
}

mongoose sub document array change value

I got a mongoose query where I want to change a comment. I receive the commentid from a react app. But it doesn't work, what could be the problem?
An example comment array follows
"comments": [
{
"createdAt": "2018-11-22T08:28:36.881Z",
"_id": "5bf668b4001de72dc089c849", // commentid
"comment": "111111111111",
"username": "kohahn21"
},
....
]
What I have tried:
edit = await Post.update(
{ 'comments._id' : commentid },
{ '$set' : { 'comments.$.comment' : comment } },
{ new: true }
);
ctx.body = edit;
ctx.body
{
"n": 1,
"nModified": 1,
"ok": 1
}
Post Schema
const Comment = new Schema({
createdAt: { type: Date, default: Date.now },
username: String,
comment: String
});
const Post = new Schema({
username: String,
comments: {
type: [Comment],
default: []
},
});
module.exports = mongoose.model('Post',Post);
I would like to receive comments, which is a modified comment layout. What should I do?
Your syntax looks correct. But instead of 'items' it should be 'comments'.
Try Post.update( { 'comments._id' : commentid }, {'$set' : { 'comments.$.comment' : comment } });
btw the new flag is only available for find-and operators.

mongoose find by ObjectId

I'm defining a mongoose schema like this
var accountPostSchema = new mongoose.Schema({
account: {
id: { type: mongoose.Schema.Types.ObjectId, ref: 'Account' }
},
post: {
id: { type: mongoose.Schema.Types.ObjectId, ref: 'Post' }
}
});
app.db.model('AccountPost', accountPostSchema);
When a user(account holder) create a post, I save the post in a Post schema and get the 'postId'. Then I save the 'postId' and the 'accountId'
in the above accountPostSchema like this
var fieldsToSet = {
post: {
id: postId
},
account: {
id: accountId
}
};
db.models.AccountPost.create(fieldsToSet, function(err, accountPost) {
if (err) {
// handle error
}
// handle success
});
After entering few postId's and accountId's, I see the following results in the mongo shell
> db.accountposts.find({})
{ "_id" : ObjectId("5835096d63efc04da96eb71e"), "post" : { "id" : ObjectId("5835096d63efc04da96eb71d") }, "account" : { "id" : ObjectId("5833c920c868d7264111da69") }, "__v" : 0 }
{ "_id" : ObjectId("583509e12052c7a2a93c4027"), "post" : { "id" : ObjectId("583509e12052c7a2a93c4026") }, "account" : { "id" : ObjectId("5833c920c868d7264111da69") }, "__v" : 0 }
Now how do I find all the matching 'Posts' given an accountId? (not the postId's)
For example if I the accountId is 583509e12052c7a2a93c4026, I need to find Posts with Post._id=5835096d63efc04da96eb71d and Post._id=583509e12052c7a2a93c4026
What is the query I should run to get the matching Posts?
I think, you should follow this way to get all the posts associated with particular accountid.
db.accountposts.find({'account.id' : accountId})
.populate('post.id')
.exec();
First, I would suggest changing your Schema to the following
var accountPostSchema = new mongoose.Schema({
account: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Account'
},
post: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}
});
This actually makes more sense, especially when you try to populate the subdocuments. Actually, I would say this Schema is useless. Why don't you define your Post schema like the following?
var PostSchema = new mongoose.Schema({
poster: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Account'
},
message: String
});
If you use the latter code, you could execute the following query to get all posts by a particular user:
db.posts.find({poster: accountId}, function(dbErr, userPosts) {
if(dbErr) {
// Handle the error.
}
// Do something with the posts by accountId in the array userPosts.
});
The advantages of removing the id field from poster becomes clear once you try to populate poster. If you defined poster as an object with the field id and try to populate it, you will need to access data about the poster as such:
posterName = retrievedPost.poster.id.name;
Alternatively, by just making the poster field an ObjectId directly, you can access the populated user more directly:
posterName = retrievedPost.poster.name;

How to update array in mongodb using mongoose

when i try to update it dose not throw back any error it goes OK but when i check my datebase nothing i their updated nothing is modified pls help
this is my db
{
"_id" : ObjectId("56651f0e4905bd041cad0413"),
"creator" : ObjectId("566299dd17990464160ae27a"),
"content" : "this is my joke 2",
"created" : ISODate("2015-12-07T05:54:22.858Z"),
"__v" : 15,
"comments" : [
{
"posteruserId" : "5665e6867185d87c1e71dbdc",
"postedBy" : "lawrence nwoko",
"postterscomment" : "good joke",
"_id" : ObjectId("56660745f644c2501116acce")
},
{
"posteruserId" : "5665e6867185d87c1e71dbdc",
"postedBy" : "lawrence nwoko",
"postterscomment" : "good joke",
"_id" : ObjectId("56660b6d33c245c012104fdc")
}
]
}
this is my schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var JokesSchema = new Schema({
creator: {type: Schema.Types.ObjectId, ref: 'User'},
content: String,
created:{type:Date, default: Date.now},
comments: [{
text: String,
postedBy: String,
posteruserId :String,
date: String,
postterscomment:String
}]
})
module.exports = mongoose.model('Jokes_db', JokesSchema)
here i my post funtion
api.post('/update', function(req, res) {
// Joke.findById("56651f0e4905bd041cad0413", function (err, meeting) {
Joke.update({_id: "5665e6867185d87c1e71dbdc", 'comments._id' : "56660745f644c2501116acce"},
{'$set': {
'comments.$.postterscomment': "working"
}},
function(err, numAffected) {
if(err){
console.log(err)
}else{
res.json(numAffected)
}
}
);
});
It has been three days of trying to fix this problem but by his grace I have done it without help the problem user that I was not using the right id to make the query thanks for your help guys I hope this helps another user
api.post('/editecomments', function(req, res) {
Joke.update({_id: "56651f0e4905bd041cad0413", 'comments._id' : "56660745f644c2501116acce"},
{'$set': {'comments.$.postterscomment': 'working'}},
function(err, numAffected) {
if(err){
console.log(err)
}else{
res.json(numAffected)
}
}
);
});

Resources