How to search in mongoDB if an element is in an array - node.js

I'm creating the backend of my project. In this project, there are some groups, and each groups has its partecipant. I would like to make a function in nodejs that retrive all the groups that, in the partecipant field(which is an array), has a given user.
Here is the schema of group:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const GroupSchema = new Schema({
name: {
type: String,
required: true,
unique: true,
},founder:{
type:String,
required: true,
}, partecipants:{
type: Array,
required:false,
}, files: {
type:Array,
required: false,
}
})
const Group = mongoose.model('Group', GroupSchema);
module.exports = Group;
For now, I wrote only this:
const getGroupByUser = (req, res) => {
const user = req.body.user;
Group.find()
.then(files => res.json(files))
.catch(err => res.status(400).json('ERROR:'+err))
}
But it obviusly returns all the groups. I don't know if there is a way to make it in the promise, or if I have to cycle throught the array, like a linear search, but for multiple cases. Any idea? Thank you

const getGroupByUser = (req, res) => {
const user = req.body.user;
const id = req.query.id;
// if id is saved as objectId covert it using Types.ObjectId(id)
Group.find({partecipants: id})
.then(files => res.json(files))
.catch(err => res.status(400).json('ERROR:'+err))
}
using {partecipants: id} you tell to mongoDb to find all group that have into the array the userId you pass in query params

Related

How to use populate in mongoose?

I have two collections where one holds list of systems and the other holds list of battery attached to the system. I want to use populate method so that when I run the query using system id it shows me the details of battery is also shown.
My schema for system and battery are as follows.
const mongoose = require('mongoose');
const { Schema } = mongoose;
const SystemSchema = new Schema(
{
serialNumber: String,
location: String,
BPIDs: [
{
type: Schema.Types.ObjectId,
ref: 'batteryPack'
}
]
},
{
timestamps: true
}
);
const Systems = mongoose.model('system', SystemSchema);
module.exports = Systems;
My battery model is as follows:
const mongoose = require('mongoose');
const { Schema } = mongoose;
const batteryPackSchema = new Schema(
{
systemSerialNumber: String,
batteryID: Number,
batteryVoltage: Number,
totalCurrent: Number,
stateOfCharge: Number
{
timestamps: true
}
);
const BatteryPacks = mongoose.model('batteryPack', batteryPackSchema);
module.exports = BatteryPacks;
My query route is as follows:
router.get('/details/:id', async (req, res) => {
try {
const deviceDetails = await Systems.findOne({ _id: req.params.id }).populate('batteryPack').lean();
return res.status(200).send({
deviceDetails
});
} catch (error) {
return res.status(500).send(error.stack);
}
});
On running query through postman it shows the following error:
MongooseError: Cannot populate path batteryPack because it is not in your schema. Set the strictPopulate option to
false to override.
at getModelsMapForPopulate
I was passing wrong argument inside populate method. The code is working flawlessly now.
const deviceDetails = await Systems.findOne({ _id: req.params.id }).populate('BPIDs').lean();
const deviceDetails = await Systems.findOne({ _id: req.params.id },{},{
populate: { path: 'BPIDs' },
lean: true,
})

upload array in mongoDB using express and node

I need to insert an array in mongoDB but an empty array is inserted all the time. What am I doing wrong?
My schema
const taskSchema = new Schema({
username: { type: String, required: true },
title: { type: String, required: true },
subtasks: [String] //how to define array as type here?
}, {
timestamps: true,
});
data to be updated:
{
"username": "test",
"title": "test",
"subtasks": ["task1", "task2"]
}
Update: it works now.
I had an err in route file, I had "subtasksArray" instead of subtasks there:
const router = require('express').Router();
let TodaysTask = require('../models/todaysTask.model');
router.route('/add').post((req, res) => {
const username = req.body.username;
const title = req.body.title;
const subTaskArray = req.body.subtasksArray; //it should be subtasks here
const newTodaysTask = new TodaysTask({
username,
title,
subtasksArray
});
newTodaysTask.save()
.then(() => res.json('Task added!'))
.catch(err => res.status(400).json('Error: ' + err));
});
you defined the attribute tasks but are trying to insert subtasks.
Maybe define the attribute subtasks

Submit a model in Mongoose that contains an array with ObjectID's

I have an object called company that inside I have name(String) and locations(Array)
Inside locations I want to have a key called name that the user will generate, and second key generated by using ObjectID.
Unfortunately I can't get this to work as expected.
Example from Postman. Note that the locations didn't get _id.
What is going wrong?
My model
const mongoose = require('mongoose')
const companySchema = mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
name: String,
locations: [
{
_id: mongoose.Schema.Types.ObjectId,
name: String
}
]
})
module.exports = mongoose.model('Company', companySchema)
My controller
createCompany: (req, res) => {
const { name, locations } = req.body
const company = new Company({
_id: new mongoose.Types.ObjectId(),
name: name,
locations: locations
})
company
.save()
.then(() => {
res.status(200).json({
company
})
})
.catch(error => {
res.status(500).json({
error
})
})
},
Mongoose will create _id for the top level and nested array of documents itself, which is a default behaviour.
So defining schema with only the fields that you want should be it.
const companySchema = new mongoose.Schema({
name: String,
locations: [
{
name: String
}
]
});
module.exports = mongoose.model("Company", companySchema);
OR
const locationSchema = new mongoose.Schema({
name: String
});
const companySchema = new mongoose.Schema({
name: String,
locations: [locationSchema]
});
module.exports = mongoose.model("Company", companySchema);
And subsequently you don't need to create the _id from the Model object as well.
const company = new Company({
name: name,
locations: locations
});
company
.save()
.then(() => {})
.catch(e => {});

EXPRESS GET info on user

Hello I want to be able to pass a user into a get request to see what items they have posted.
Here is the GET request
// #route GET with NAME
// #desc GET All ITEMS WITH NAME
// #access private
router.get('/:user', (req, res) => {
Item.findBy(req.params.user)
.sort({ date: -1})
.then(items => res.json(items))
});
Then I want to be able to pass it through the actions file.
export const getItems = () => dispatch => {
dispatch(setItemsLoading());
axios.get(`/api/items/`).then(res =>
dispatch({
type: GET_ITEMS,
payload: res.data
})
)
.catch(err =>
dispatch(returnErrors(err.response.data, err.response.status))
);
}
Here is the item modal if anyone was wondering
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
//Create Schema
const ItemSchema = new Schema({
name:{
type: String,
required: true
},
user:{
type: String,
required: true
},
date:{
type: Date,
default: Date.now
}
});
module.exports = Item = mongoose.model('item', ItemSchema);
The expected results of this would be
http://localhost:3000/{username}
Product list
"name":"Item name"
"date": "mm/dd/yy"
I am also new to mongoDB/Json. I am coming from using SQL.
In this case I would use req.query.user and the url would be http://localhost:3000/?username.
Then in router.get method pull the correct db data from mongoDB and res.send data to client.

Mongoose populate not working for nested object

Client.js
const mongoose = require("mongoose");
var Schema = mongoose.Schema;
const clientSchema = new mongoose.Schema(
{
name: { type: String, required: true, default: "" },
}, {
timestamps: true
}
);
module.exports = mongoose.model("Client", clientSchema);
User.js
const mongoose = require("mongoose");
var Schema = mongoose.Schema;
const userSchema = new mongoose.Schema({
name: { type: String, required: true, default: "" },
clients: [{
client: {
type: Schema.Types.ObjectId,
ref: "Client",
default: null
},
user_group: {
type: Number
default: null
}
}]
}, { timestamps: true });
module.exports = mongoose.model("User", userSchema);
auth.js (Where trying to populate Clients)
const express = require("express");
const router = express.Router();
const User = require("../models/User");
const Client = require("../models/Client");
router.post("/users", (req, res) => {
let params = req.body;
let total_client = [];
User.findOne({
email: params.email
})
.populate({
path: "clients.client",
model: Client
})
.exec((err, user) => {
console.log(user);
res.send(user);
});
});
module.exports = router;
Please check the above code. I have given code examples of my two models user.js and client.js. In user schema, I have referenced client inside an array object. While querying user, the client is not population. Please help me to get this thing done. Thanks in advance.
The following expects you to provide a name in the json body of your post request (your example uses email which does not exist in the user model). Also, your model is already defining the ref: Client and so you can simplify your request to just include the path clients.client.
router.post("/users", async (req, res) => {
const { name } = req.body;
const user = await User.findOne({ name: name }).populate('clients.client').exec();
res.send(user);
});
Solved this problem just adding an extra parameter in module export of client.js file
module.exports = mongoose.model("Client", clientSchema, "client");

Resources