I tried to find the user from the mongoose db - node.js

This is my mongoose schema for movieLibrary
const mongoose = require('mongoose')
const movieSchema = new mongoose.Schema({
movieName:{
type: String,
required: true,
trim: true
},
movieCast:[{
actor:{
type: String,
required: true
},
actress:{
type: String,
required: true
}
}],
yearOfRelease:{
type : Date,
default : Date.now
},
movieDirector:{
type: String,
required: true
},
genre:{
type: String,
required: true
},
rating:{
type: Number,
required: true
}
})
module.exports = mongoose.model('movieLibrary',movieSchema)
I want to find the movie detail by passing the actor name as a parameter
I tried this:-
const movies = await Movie.find({
"movieCast": {
$elemMatch: {
"actor": actor
}
}
})
But i get empty array as the output , Can you help me what issue might have occured , I get the correct answer in robo 3T, but not getting in postman.

I don't see anything wrong in your implementation. I have done the same thing like you except I have hard coded the value in query itself. It's working fine for me.
Data which is available in DB,
{
"_id" : ObjectId("5ed9c47b39d18ba11f4c8f10"),
"movieName" : "Titanic",
"movieCast" : [
{
"actor" : "Leonardo",
"actress" : "Winslet"
}
],
"yearOfRelease" : ISODate("1994-04-01T23:20:19.199Z"),
"movieDirector" : "James Cameroon",
"genre" : "History",
"rating" : 8.8
}
And the query impl,
async test() {
let result = await Test.find({
"movieCast": {
$elemMatch: {
"actor": 'Leonardo'
}
}
});
console.log(JSON.stringify(result));
return result;
}
I think either you could have passed the wrong actor value or none is passed.

Related

Updating array of objects inside an object mongodb node

I have a mongoDb model defined as follows:-
var mongoose = require("mongoose");
const postModel = new mongoose.Schema({
postId: {
type: String,
unique: true,
required: true
},
authorId: {
type: String,
required: true
},
post: {
authorHandle: {
type: String,
required: true
},
heading: {
type: String,
required: true
},
message: {
type: String,
required: true
},
creationDate: {
type: Date,
required: true
},
image: { type: Array },
video: { type: Array },
comments: {
type: Array
}
}
});
module.exports = mongoose.model("postModel", postModel);
Now I have a sample value of a document of the above model, suppose:-
postId: "aaa",
authorId: "bbb",
post: {
authorHandle: "someone#123",
heading: "hello",
message: "post 1",
creationDate: "some creation date string(please ignore this is irrelevant to my question)",
image: [],
video: [],
comments: [
{ commentId: "1", message: "Something", createdAt: sometime },
{ commentId: "2", message: "Something else", createdAt: sometime2 },
{ commentId: "3", message: "Something other", createdAt: sometime3 },
]
}
Now say the user wants to update the comment with commentId 2 of this post with postId "aaa". My question is that what is the best way to use the findOneAndUpdate() method to solve this problem?
const PostModel = require("./models/PostModel"); //just importing the model that is defined above
//the below is happening inside a request handler in Node + Express
PostModel.findOneAndUpdate(
//what to do here
)
What I have tried is pulling out that whole object and replacing it with a new object with the new message. But that doesnt seem like a very efficient way. Any and all help is greatly appreciated!
You should write:
const updatedPost = await PostModel.findOneAndUpdate(
{ postId: 'aaa', 'post.comments.commentId': 2 },
{ 'post.comments.$.message': 'Updated message'},
{ new: true }
)

How to find the length of an array by filtering by a parameter value in Mongoose

I was building a chat server, where i need to get the number of messages that is not marked as
seen . below is my schema
const ChatSchema = mongoose.Schema({
chatId: { type: String, required: true, unique: true },
messages: [
{
message: { type: String, required: true },
sendBy: { type: String, required: true },
sendTo: { type: String, required: true },
seen: { type: Boolean, default: false },
date: { type: Date, default: Date.now()}
},
],
})
I have tried the following code but it always returns 1
const unSeenCount=await Chat.find({ chatId: chatId },
{ messages : { $elemMatch : { seen : false } } })
console.log(`unseen count is ${unSeenCount.length}`);
The first object in the mongoose query is the filter which is what you were using in the second object. You can also use count to get the count returned by the filter query.
Try this:
const unSeenCount = await Chat.count({
messages: {
$elemMatch: {
seen: false
}
}
})
console.log(`unseen count is ${unSeenCount}`);
you can use the countDocuments Method
const unSeenCount=await Chat.countDocuments({{ chatId: chatId },
{ messages : { $elemMatch : { seen : false } } }})
console.log(`unseen count is ${unSeenCount}`);

MongoDB collection.aggregrate accept only two arguments

I am trying the aggregation in mongoose. When I run that aggregation, it show the error. What am I missing?
const data = await Rooms.aggregate([{ $match: { adminID: "1234" } }]);
Error is like that
MongoInvalidArgumentError: Method "collection.aggregate()" accepts at most two arguments
Edit -- code for Rooms Schema
const mongoose = require('mongoose');
const Rooms = new mongoose.Schema(
{adminID: {
type: String,
required: true,
},
roomID: {
type: String,
required: true,
},
roomName: {
type: String,
required: true,
},
users: [
{
id: {
type: String,
required: true,
unique: true,
},
},
],
},
{ timestamps: true } );
module.exports = mongoose.model("rooms", Rooms);
solution 1 : downgrade mongoose to version 5
solution 2 :
const data = await Rooms.aggregate([{ $match: { adminID: "1234" } }],"adminID roomID roomName users");
in new version second argument is selected fields in out put,
or use :
const data = await Rooms.aggregate.match({ adminID: "1234" } )

i want to create a document with array field in mongodb

In mongodb schema i just want to add an array in this schema but have some problem when I insert data , all time return an error string "This library (validator.js) validates strings only"
In Model:
let prescriptionSchema = new Schema({
appointment_id: {
required: [true, 'Appointment id is required'],
type :Schema.Types.ObjectId,
ref: 'Appointments'
},
remarks: {
type: String,
},
diagnosis_description:{ type : Array , "default" : [] },
diagnosis: [{
diagnosis_description: {
type: String,
},
}],
investigation: [{
test_name: {
type: String,
},
test_description: {
type: String,
},
}],
medicine: [{
medicine_name: {
type: String,
},
medicine_dosage: {
type: String,
},
medicine_power: {
type: String,
},
}]
},
{timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
}});
In controller i just write a console log , so i thing problem is in mongodb , mongo can't understand then array, please help.....
In postman :
{
"appointment_id": "5d3ab1a4590ad324b2abdb76",
"remarks" : "Next checkup after one month",
"diagnosis":[
{
"diagnosis_description": "Fiver"
}
],
"investigation":[
{
"test_name" : "Blood",
"test_description" : "Dengu"
},
{
"test_name" : "Blood",
"test_description" : "HIV"
}
],
"medicine":[
{
"medicine_name":"Paracetamol",
"medicine_dosage":"650",
"medicine_power":"AM"
}
]
}
const path = require('path'),
router = require('express').Router(),
dir = ${path.dirname(__dirname)}/controllers,
helperLib = require(path.resolve('./config/lib/helper_lib'));
This is routes :
let ReadDirectory = new helperLib.read_directory.readDirectory();
let Middleware = new helperLib.middleware();
//# require all controllers for this module
let fileObj = ReadDirectory.requireFiles(dir);
//# routes mapping
router
.put('/addprescription', fileObj['prescription.account'].addprescription);
//.get('/prescriptionlist', fileObj['prescription.account'].prescriptionlist)
//.put('/updateprescription', Middleware.decodeToken, fileObj['prescription.account'].updateprescription);
module.exports = {
router: router,
base: '/api/prescription'
};
Please provide the code that is responsible for using validator.js package. The error which occurs is saying that you're probably trying to use validate function from this library which takes only string parameter.
This library validates and sanitizes strings only.
Link: validator.js package usage

Mongoose populate() returns empty array with no errors

I've been trying to get this populate thing to work, but I'm getting issues because I am not getting the expected results, and no errors to work with. Just simply an empty array.
My models look like this. Each their own file
var mongoose = require( 'mongoose' );
var upgradeSchema = new mongoose.Schema({
type: {
type: String,
default: "Any"
},
ability: String,
ability_desc: String,
level: Number,
tag: String
});
mongoose.model('Upgrade', upgradeSchema);
and the other
var mongoose = require( 'mongoose' );
var crypto = require('crypto');
var jwt = require('jsonwebtoken');
var userSchema = new mongoose.Schema({
email: {
type: String,
unique: true,
required: true
},
hero: {
level: Number,
name: String,
type: {
path: String,
heroType: String
},
upgrades: [{
type: mongoose.Schema.Types.ObjectId, ref: 'Upgrade'
}],
unspent_xp: Number,
total_xp: Number,
},
armyTotal: {
type: Number,
default: 0,
max: 5000
},
army:[{
foc_slot: String,
unit_name: String,
unit_cost: Number
}],
username: {
type: String,
required: true,
unique: true,
},
faction: String,
name: {
type: String,
required: true
},
hash: String,
salt: String,
roles: {
type: String,
default: 'player' }
});
And I'm trying to do this
module.exports.profileRead = function(req, res) {
User
.findById(req.payload._id)
.populate('hero.upgrades')
.exec(function (err, user) {
if (err){
console.log(err);
} else {
res.status(200).json(user);
console.log("success");
}
});
}
};
This is an example of a user
{
"_id" : ObjectId("57b4b56ea03757e12c94826e"),
"hash" : "76",
"salt" : "2",
"hero" : {
"upgrades" : [
"57b42773f7cac42a21fb03f9"
],
"total_xp" : 0,
"unspent_xp" : 0,
"type" : {
"heroType" : "Psyker",
"path" : ""
},
"name" : "Jon Doe"
},
"username" : "michaelzmyers",
"faction" : "Grey Knights",
"email" : "email#gmail.com",
"name" : "Michael Myers",
"roles" : "player",
"army" : [],
"armyTotal" : 625,
"__v" : 3
}
Now, I've tried an array of just the strings with ObjectId's in them, similar to the eample, and I've also tried using ObjectId("STRINGHERE") and no luck. They both return just an empty array. However, if i get rid of the populate call (or change the contents inside populate from hero.upgrades to just hero, or upgrades) then it just returns an array of strings. I feel like the problem is with populate and how I'm using it. HOWEVER, when I had just a single upgrade in my databse (the test upgrade), everything worked fine. Now nothing works. Any thoughts? I'd be happy to provide more code if needed.
I found that during my little research that it will work:
User
.findById(req.payload._id)
.populate({
path: 'hero.upgrades',
model: 'Upgrade'
})
.exec(function (err, user) {
if (err){
console.log(err);
} else {
res.status(200).json(user);
console.log("success");
}
});
}
It looks like when user is giving nested object notation i.e. hero.upgrades into populate method, Mongoose got problems with detecting referring model.

Resources