How to search in multiple collections in MongoDB using Mongoose - node.js

I have two collections User and UserType :-
var User = new mongoose.Schema({
username: {
type: String,
required: true,
},
userType: {
type: ObjectId,
ref: "UserType",
required: true,
},
});
var UserTypeSchema = new mongoose.Schema(
{
type: String,
type_code: Number,
type_description: String,
},
{ timestamps: true }
);
I want to search user based on username and typecode which is in UserType Collection.
I tried this code: -
User.findOne({
username: mobileNumber,
userType: { type_code: userTypeCode },
})
.populate("userType");
please correct this query.

you must to filter out populate results, with match option
In your case answer would be::
User.findOne({
username: mobileNumber,
}).populate({
path: "userType",
match: { type_code: userTypeCode },
});
you can check the documentation

Related

Mongoose query to list all the groups that a user joined

const groupSchema = new Schema({
name: { type: String, default: "", required: true },
participants: [{
type: Schema.Types.ObjectId,
ref: 'User'
}],
});
const userSchema = new Schema({
username: { type: String, default: "", required: true },
name: { type: String, default: "", required: true },
});
I'm trying to fetch all the groups the given user is joined. This is my try
userModel.findOne({ username: data.username }, function(err, user) {
if (user) {
groupModel
.find({"participants":{"$in":[user]}
.populate('participants')
.exec(function(err, result) {
.....
}
}
});
I'm getting an empty list in for the above query
Thank you
Look like you just need to do:
groupModel.find({participants: user._id}).exec(...

Mongoose WHERE OR LIKE syntax on referenced schemas

I have the following 2 schemas (Clinic and User):
const ClinicSchema = new Schema({
name: {
type: String,
unique: true,
required: true
},
createdBy: {
type: Schema.Types.ObjectId,
ref: 'user'
},
createdAt: Date,
updatedBy: {
type: Schema.Types.ObjectId,
ref: 'user'
},
updatedAt: Date
});
And Here is the user Schema
const UserModelSchema = new Schema({
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
firstName: {
type: String,
required: true,
},
lastName: {
type: String,
required: true,
},
roles: {
type: [String],
required: true,
}
});
I want to write a query that will search a string that is contained in the clinic name OR createdBy(user) name OR createdBy(user) last name, and return all the clinics where either the clinic name matches part of the search string OR the created by name matches part of the search string OR the created by last name matches part of the search string here is the pseudo SQL alternative of what I am trying to explain:
SELECT * FROM clinics
JOIN users on clinics.createdBy = users.id
WHERE clinics.name LIKE '%STRING%'
OR users.firstname LIKE '%STRING%'
OR users.lastname LIKE '%STRING%'
I have been searching for this solution for the past 2 days and can't seem to be able to figure it out, more specifically I am trying to add the WHERE OR functionality to the following query:
const clinicsQuery = Clinic.find({
name: new RegExp(req.query.searchTerm, 'i')
});
....
const clinicsList = await clinicsQuery
.limit(limit)
.skip(skip)
.populate('createdBy', ['firstName', 'lastName']);
It can be performed with a $lookup
const clinicsQuery = Clinic.aggregate([{
$lookup:
{
from: 'user',
localField: 'createdBy',
foreignField: '_id',
as: 'user'
}},
{ $unwind: "$user"}
{
$match: {
$or: [
{"user.firstname": new RegExp(req.query.searchTerm, 'i')},
{"user.lastname": new RegExp(req.query.searchTerm, 'i')},
{ name: new RegExp(req.query.searchTerm, 'i')}
]
}
},
{$limit: limit}
]);
User will be in "user" field in the result. But you won't have a mongoose ready object :/

Mongoose find documents where field = req.body.user

I have a user schema and a post schema, wherein a user has many posts. I would like to return all posts that the user has on a route called '/post/dashboard'.
Here is my schemas:
let UserSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
},
password: {
type: String,
default: null,
},
profile_pic: {
type: String,
default: '/img/profilepic.png',
},
posts: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Post'
}
})
let PostSchema = new Schema({
title: {
type: String,
},
description: {
type: String,
}
original_poster: {
type: Schema.Types.ObjectId,
ref: 'User',
required: true
},
tags: {
type: [String]
}
})
So, for example something like:
app.get('/', (req,res) => {
Post.find({ original_poster: req.session.user }).then((posts) =>{
res.send(JSON.stringify(posts));
}) //where req.session.user is an id (the logged in user's object id or _id)
})
Essentially in sql syntax it might be something like:
SELECT * FROM POSTS WHERE ORIGINAL_POSTER = <req.session.user>
What is the proper way to return all posts by the req.session.user?
It seems that original_poster field represent a reference to User's model, If req.session.user is stored as a string you have to cast it to objectID:
const mongoose = require('mongoose');
...
let userId = mongoose.Types.ObjectId(req.session.user);
Post.find({ original_poster: userId }).then((posts) => {
res.send(JSON.stringify(posts));
});

Mongoose Add New Field To Collection (Node.js)

I have a schema:
var userSchema = new Schema({
name: String,
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
admin: Boolean,
created_at: Date,
updated_at: Date
});
Let's assume I have made 100 Users using this schema.
Now I want to change the schema:
var userSchema = new Schema({
name: String,
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
admin: Boolean,
created_at: Date,
friends: [Schema.Types.ObjectId], //the new addition
updated_at: Date
});
I need all new Users to have this field. I also want all of the 100 existing Users to now have this field. How can I do this?
You can use Mongoose Model.update to update all your documents in the collection.
User.update({}, { friends: [] }, { multi: true }, function (err, raw) {
if (err) return handleError(err);
console.log('The raw response from Mongo was ', raw);
});
I don't recommend to do it in production if the collection is big, since it is a heavy operation. But in your case it should be fine.
Using the query interface in a client app or your terminal you could do:
db.users.updateMany({
$set: { "friends" : [] }
});
Here's the docs reference.
it doesn't work for me :x
Here is my code
let test = await this.client.db.users.updateMany({
$set: { "roles" : [] }
});
and the output
{ ok: 0, n: 0, nModified: 0 }
I don't know how to do, i tried a lot of things and uh it doesn't work :'(
EDIT: I found, here is my code
await this.client.db.users.updateMany({ }, [ {$set : { "roles": []} } ]);

using a key value other than Schema.Types.ObjectId in mongoose

I am creating a collection w/n mongo using mongoose to populate related users. I have clinicians and patients. I want patients to have an array of clinicians as they are enrolledwith. Later I'll load a dashboard for clincian based on patient user "enrolledWith: "
Likely clincians will provide their email to patients to be marked in rolled. emails are username.
Can I use username for the Schema.Types.username?
var mongoose = require('mongoose');
var userSchema = mongoose.Schema({
name: String,
phoneNumber: String,
username: {
type: String,
required: true
},
password: {
type: String,
required: true
},
patient: {
// role: Boolean,
enrolledWith: [
{
type: mongoose.Schema.username,
ref: 'User'
}
],
gameTotalScore: Number,
},
// clinician: {
// role: Boolean
// },
role: {
type: String,
required: true
},
});

Resources