Nodejs express filter data by query - node.js

I need to run the query by find like I pass id and data only with that Id will display but the issue is it's showing all data means it's not filtering.
I am finding data like this
router.get('/getannouncementsbyrestaurant/:id', async (req, res) => {
let getannouncementsbyrestaurant = await Announcements.find({ restaurants: req.params.id }).populate(['announcementRestaurants']);
if (!getannouncementsbyrestaurant) {
return res.status(400).json({ success: false, message: "something went wrong" })
}
res.status(200).json({ success: true, data: getannouncementsbyrestaurant })
})
and here is the model
const mongoose = require('mongoose');
const announcementsschema = new mongoose.Schema({
announcementName: {
type: String,
required: true
},
announcementDescription: {
type: String,
required: true
},
announcementCountry: {
type: String,
required: false
},
announcementCity: {
type: String,
required: false
},
announcementStreet: {
type: String,
default: ''
},
announcementRestaurants: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'restaurants'
},
announcementCreatedOn: {
type: Date,
default: Date.now
}
})
announcementsschema.virtual('id').get(function () {
return this._id.toHexString();
});
announcementsschema.set('toJSON', {
virtuals: true,
});
exports.Announcements = mongoose.model('Announcements', announcementsschema);
exports.announcementsschema = announcementsschema;
Don't know why its showing all data
here is example json
"data": [
{
"_id": "631a4c9c2c4fca7afc0f23f5",
"announcementName": "Mega Sale 10% off",
"announcementRestaurants": {
"_id": "631a4af62c4fca7afc0f238f",
"restaurantName": "Mega Restaurant",
},
"id": "631a4c9c2c4fca7afc0f23f5"
},
{
"_id": "631a51b72c4fca7afc0f2449",
"announcementName": "Sale upto 90%",
"announcementRestaurants": {
"_id": "631a51752c4fca7afc0f2434",
"restaurantName": "McDonalds",
},
"announcementCreatedOn": "2022-09-08T20:33:59.870Z",
"__v": 0,
"id": "631a51b72c4fca7afc0f2449"
}
]
I am passing announcementRestaurants._id in param and need to filter with that.

Your schema doesn't have the field restaurants. The corresponding field is announcementRestaurants. So the query should be:
let getannouncementsbyrestaurant =
await Announcements.find({ announcementRestaurants: req.params.id }).populate(['announcementRestaurants']);
Or
let getannouncementsbyrestaurant =
await Announcements.find({ announcementRestaurants: mongoose.Types.ObjectId(req.params.id) }).populate(['announcementRestaurants']);

Related

Nodejs express populate sub array data

I have relative field and in relative I have subRelatives and it continues like nested array. Mean in subRelatives I have subRelatives and some time its 10 times continues process.
My code
router.get(`/userTree/:id`, async (req, res) => {
const userTrees = await Tree.find({createdBy: req.params.id})
.populate(
["createdBy",
{
path: "relatives",
populate: {
path: "subRelatives",
populate: {
path: "subRelatives",
populate: "subRelatives",
},
},
}
]);
if (!userTrees) {
res.status(500).json({success: false});
}
res.send({success: true, data: userTrees});
});
I have added populate but it populate first 2 sub relative and then shows MongooseIds only without populating. So I need to added manually some more populate methods so it will run but its crashing because of lot of data now.
and data look like this.
{
"success": true,
"data": {
"_id": "62dad5c6aff2337dc84d9b40",
"treeName": "test1",
"createdBy": {
"_id": "62d8619cebd6543477c5b7d8",
"userName": "test1",
"userEmail": "test1#gmail.com",
"userFamilyTrees": [
"62d8c713547ba80854d89d59"
]
},
"relatives": [
{
"_id": "62dad5c7aff2337dc84d9b44",
"firstName": "tesads",
"subRelatives": [
{
"_id": "62db1cf186b7012ed9937517",
"firstName": "asdasd",
"subRelatives": []
},
{
"_id": "62db1d0d86b7012ed9937522",
"firstName": "asd",
"subRelatives": []
},
{
"_id": "62dc24c15e6f5ea436cce14b",
"firstName": "julia",
"subRelatives": [
{
"_id": "62dc24c15e6f5ea436cce14b",
"firstName": "julia",
"subRelatives": [
"62dc253bd2119bea52f4f9af"
]
}
]
},
{
"_id": "62dc24fcd2119bea52f4f99d",
"firstName": "julia",
"subRelatives": []
}
]
}
]
}
}
This is my Tree Schema
const mongoose = require('mongoose')
const treeSchema = new mongoose.Schema({
treeName: {
type: String,
required: true
}, image: {
type: String,
default: ''
},
treePrivacy: {
type: Boolean,
required: true
},
treeNote: {
type: String,
default: ""
},
createdBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users',
required: true,
},
createDate: {
type: Date,
default: Date.now,
},
relatives: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'relatives',
},],
usersInTree: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'users',
},],
media: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'media',
},]
});
treeSchema.virtual('treeID').get(function () {
return this._id.toHexString();
});
treeSchema.set('toJSON', {
virtuals: true
})
exports.Tree = mongoose.model('trees', treeSchema)
exports.treeSchema = treeSchema;
This is relative Schema
const mongoose = require('mongoose')
const relativeSchema = new mongoose.Schema({
firstName: {
type: String,
},
lastName: {
type: String,
}, image: {
type: String,
},
relativeEmail: {
type: String,
},
relativeType: {
type: Number,
},
// relative grandfather0, father1, mother2, wife3, sister4, brother5, child6
treeID: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users',
required: true,
},
subRelatives: [{
type: mongoose.Schema.Types.ObjectId,
ref: 'relatives',
}],
parentRelative: {
type: mongoose.Schema.Types.ObjectId,
ref: 'relatives',
},
userID: {
type: mongoose.Schema.Types.ObjectId,
ref: 'relatives',
required: false
}
});
relativeSchema.virtual('relativeId').get(function () {
return this._id.toHexString();
});
relativeSchema.set('toJSON', {
virtuals: true
})
exports.Relatives = mongoose.model('relatives', relativeSchema)
exports.relativeSchema = relativeSchema;
This is post api for tree
router.post('/createTree', uploadOptions.single('image'), async (req, res) => {
const file = req.file;
if (!file) return res.status(400).send('No image in the request');
const fileName = file.filename;
const basePath = `${req.protocol}://${req.get('host')}/public/uploads/`;
var userintree = [];
const userExist = await User.findById(req.body.createdBy);
if (!userExist) return res.status(400).send({ success: false, message: 'UserID is not correct' })
userintree.push(req.body.createdBy);
let createtree = new Tree({
treeNote: req.body.treeNote,
treeName: req.body.treeName,
treePrivacy: req.body.treePrivacy,
createdBy: req.body.createdBy,
image: `${basePath}${fileName}`,
usersInTree: userintree
});
createtree = await createtree.save();
if (!createtree) return res.status(400).send({ success: false, message: 'Issue to create a tree' })
userExist.userFamilyTrees.push(createtree._id.toHexString())
const user = await User.findByIdAndUpdate(
req.body.createdBy,
{
userFamilyTrees: userExist.userFamilyTrees,
$push: {
usersInTree: req.body.createdBy
}
},
{ new: true }
)
if (user) res.status(200).send({ success: true, message: 'Tree Created.!,', data: createtree })
});
and post API for relative
router.post('/addRelative', uploadOptions.single('image'), async (req, res) => {
const file = req.file;
if (!file) return res.status(400).send('No image in the request');
const fileName = file.filename;
const basePath = `${req.protocol}://${req.get('host')}/public/uploads/`;
console.log(fileName); console.log(basePath);
console.log(req.body);
let createRelative = new Relatives({
firstName: req.body.firstName,
lastName: req.body.lastName,
relativeEmail: req.body.relativeEmail,
relativeType: req.body.relativeType,
treeID: req.body.treeID,
subRelatives: req.body.subRelatives,
parentRelative: req.body.parentRelative, image: `${basePath}${fileName}`,
});
const treeExist = await Tree.findById(req.body.treeID);
if (!treeExist) return res.status(400).send({ success: false, message: 'TreeID is not correct' })
createRelative = await createRelative.save();
if (!createRelative)
return res.status(400).send({ success: false, message: 'Something Went Wrong.!,' })
treeExist.relatives.push(createRelative._id.toHexString())
const tree = await Tree.findByIdAndUpdate(
req.body.treeID,
{
relatives: treeExist.relatives
},
{ new: true }
)
if (req.body.parentRelative) {
console.log(req.body.parentRelative)
const parent = await Relatives.findById(
req.body.parentRelative
);
// console.log(parent)
// console.log(parent)
parent.subRelatives.push(createRelative)
const user = await Relatives.findByIdAndUpdate(
req.body.parentRelative,
{
subRelatives: parent.subRelatives,
},
{ new: true }
)
// console.log(user)
if (!user) return res.status(400).send({ success: false, message: 'Something Went Wrong.!,' })
// res.send(ser);
}
res.status(200).send({ success: true, message: 'Relative Created Created.!,', data: createRelative })
});
Populate data like this
.populate(
["createdBy",
{
path: "relatives",
populate: {
path: "subRelatives",
model: "SubRelative",
},
}
]);
I've assumed that the model name refaring to subRelative is SubRelative
mongoose does support nested population, it's just that you need to specify the model field as the treeSchema does not have access to all other schema during run time. It looks like this:
const userTrees = await Tree.find({createdBy: req.params.id})
.populate(
[
"createdBy",
{
path: "relatives",
populate: {
path: "subRelatives",
model: 'relatives',
},
}
]);
mongoose does some optimizations to the query, but considering you know the exact structure you can reduce db calls and improve performance if you do this yourself instead of using populate.

How to add an array as different objects mongodb

I'm having some trouble with a post function in nodeJs
I have the next body to post:
{
"_id": "fffff-ggg-jjjjj",
"type": "",
"gamers": [
"Raul Andres",
"Pedro",
"Juan"
]
}
(I shouldn't change the post body)
And this is my Schema:
var gameSchema = new Schema({
_id: {
type: String,
required: true,
trim: true
},
type: {
type: String,
trim: true
},
gamers: [{
name: {
type: String,
required: true,
trim: true
},
playerBet: {
type: Number,
trim: true
}
}],
inProgress: {
type: Boolean,
trim: true
},
});
So clearly i can't just give it the gamers just like that, so i need to get the array given in the POST body and insert every element as name field so i can add it in the collection.
expected output
{
"id": "fffff-ggg-jjjjj",
"gamers": {
"5257b4d6-5c87-4871-93c3-b2b9ce04d706": {
"id": "5257b4d6-5c87-4871-93c3-b2b9ce04d706",
"name": "Raul Andres"
},
"8dda6205-f54c-4643-a017-71b6f0353319": {
"id": "8dda6205-f54c-4643-a017-71b6f0353319",
"name": "Juan"
},
"e5834d8e-5195-41fc-993e-c731dbce4fab": {
"id": "e5834d8e-5195-41fc-993e-c731dbce4fab",
"name": "Pedro"
}
},
"inProgress": false,
"winner": {
"id": "e5834d8e-5195-41fc-993e-c731dbce4fab",
"name": "Pedro"
}
}
router.post('/createGame', async (request, response, next) => {
try {
const { _id, gamers } = request.body;
const data = new gameModel({
_id,
players:{
name: gamers
},
inProgress: true,
});
await data.save();
response.json({
message: 'Game created successfully',
data
});
} catch (error) {
response.status(500).json({
message: error.message,
stack: error.stack
});
}
});
This is the way i was trying to do it but, name expects a String instead of an array
Thank any who can help me
You can create a gamers schema and add the id to the gamerSchema under the gamers key and store the gamers _id to the gamerSchema.gamers array

Want to use mongoose updateOne but it is not updating

I want to update the type: reported to type: pending under the reportStatus, but when I try it on postman I keep on getting
n:1 ,n:modified:1 and ok:1
report: [
{
category: {
type: mongoose.Schema.Types.ObjectId,
ref: "CrimeCategory",
required: true,
},
location: {
type: mongoose.Schema.Types.ObjectId,
ref: "Location",
required: true,
},
reportText: {
type: String,
required: true,
},
reportStatus: {
type: mongoose.Schema.Types.Mixed,
default: function () {
return [
{ type: "reported", date: new Date(), isCompleted: true },
{ type: "pending", isCompleted: false },
{ type: "investigating", isCompleted: false },
{ type: "solved", isCompleted: false },
];
},
},
},
],
This is the controller where I am trying to update the types that is in the model, what am I doing wrong?
const crimeReport = require("../../model/crimereport");
exports.updateReport = (req, res) => {
crimeReport
.updateOne(
{ _id: req.body.reportId, "report.reportStatus": req.body.type },
{
$set: {
"report.reportStatus.$": [
{
type: req.body.type,
date: new Date(),
isCompleted: true,
},
],
},
}
)
.exec((error, report) => {
if (error) return res.status(400).json({ error });
if (report) {
res.status(200).json({ report });
}
});
};
The postman post request:
{
"reportId": "607b2b25876fa73ec4437440",
"type":"pending"
}
This is the post result from postman:
{
"report": {
"n": 0,
"nModified": 0,
"ok": 1
}
}
It seems like, you are sending reportId in the body of post request as a string while the Mongodb document's id is of type ObjectId. You need to typecast the reportId into ObjectId, before querying to Mongodb. Since you are using Mongoose, this is the way it should be done:
mongoose.Types.ObjectId(req.body.reportId)

Trying to populate an object inside another object that is inside another object (NODE.JS)

This function gets a specific "process" and shows the following information in json: (POSTMAN)
{
"process": {
"_id": "5c18e8d1d4817811839d43d2",
"name": "Dyeing",
"colour": {
"_id": "5c18c972b39bb20769288e8f",
"name": "azul",
"category": "5c18c09f4c6baf05ea621bca",
"__v": 0
},
"__v": 0
},
"request": {
"type": "GET",
"url": "http://localhost:3000/process"
}
}
Process controller function
exports.process_get_process = (req, res, next) => {
Process.findById(req.params.processId)
.populate("colour")
.populate("category")
.exec()
.then(process => {
if (!process) {
return res.status(404).json({
message: "Process not found"
});
}
res.status(200).json({
process: process,
request: {
type: "GET",
url: "http://localhost:3000/process"
}
});
})
.catch(err => {
res.status(500).json({
error: err
});
});
};
The model for the "process" is the following schema:
const mongoose = require('mongoose');
const processSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
price: { type: Number, required: false },
colour: { type: mongoose.Schema.Types.ObjectId, ref: 'Colour', required: false },
});
module.exports = mongoose.model('Process', processSchema);
This is the Colour model:
As you can see the object "category" is inside "colour" and i want to show him in the "process" object as well.
const mongoose = require('mongoose');
const colourSchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: { type: String, required: true },
category: { type: mongoose.Schema.Types.ObjectId, ref: 'Category', required: true },
});
module.exports = mongoose.model('Colour', colourSchema);
Problem: Inside the "colour" exist a "category" object, but only shows the category id, and i want him to show all the category information. How can I populate it?
You can specify that as options for the populate function.
Process.findById(req.params.processId)
.populate({
path: 'colour',
populate: { path: 'category' }
})
.exec()

Unable to push object into array in Mongodb collection but Id is inserted

I am using comment array in my schema as fallows. I want to push comments data into that comment array using nodejs api
var Schema = mongoose.Schema;
var myfeeds = new Schema({
title: {
type: String,
required: true
},
feed: {
type: String,
required: true
},
createdBy: {
type: String,
required: true,
unique: true
},
createdDate: {
type: Date,
required: true,
default: Date.now()
},
comment: [
{
commentBy: {
type: String
},
commentText: {
type: String
},
createdDate: {
type: Date
}
}
],
likes: [
{
likesCount: {
type: Number,
required: false
},
likeBy: {
type: String,
required: false
}
}
]
});
I want to push object to this comment array. so, for that I did in this way please tell me if anything wrong in this
let _id = req.body.id;
let commentBy = req.body.commentedBy;
let commentedText = req.body.commentedText;
let commentedDate = req.body.commentedDate;
let data = {
commentBy: commentBy,
commentText: commentedText,
createdDate: commentedDate
};
MyFeeds.findByIdAndUpdate(
{ _id: _id },
{
$push: {
comment: data
}
}
)
.then((result) => {
res.status(200).json({
status: result
});
})
.catch((err) => {
res.status(500).json({
status: 'invalid',
err: err
});
});
but only id are inserted into that comment array but not the required content
"comment": [
{
"_id": "5badfd092b73fa14f4f0aa7c"
},
{
"_id": "5badfd102b73fa14f4f0aa7d"
},
{
"_id": "5badfd142b73fa14f4f0aa7e"
},
{
"_id": "5badfd31500fb11bb06b4c8a"
},
{
"_id": "5badfd35500fb11bb06b4c8b"
},
{
"_id": "5badff3d439a151190d62961"
}
],

Resources