I have a schema in Mongo like this:
const userSchema = new mongoose.Schema({
_id: {
type: mongoose.Types.ObjectId,
required: true,
},
organizationId: {
type: mongoose.Types.ObjectId,
required: true,
},
projectsId: {
type: [mongoose.Types.ObjectId],
default: []
},
roleId: {
type: mongoose.Types.ObjectId,
required: true,
},
email: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
pic: {
type: String,
default: ''
},
createdOn: {
type: Date,
default: Date.now
}
I want to find users with a specific organizationId, but mongoose returns empty array. When i try to find with an _id, email it works but when i try it with organizationId and projectsId it doesn't find it. This led me to believe there is a problem with field names which have capital letters in them.
Here is my node/express code:
const getMemberListController = async (req, res, next) => {
try {
const memberList = await User.find({organizationId: '6239b5fc3c16a8041341a3e8'});
res.status(200).json(memberList);
} catch (error) {
res.status(500).json(error);
}
}
The above returns an empty array, eventhough
User.find({_id: '623ad5c75d17751ff664a9ae'})
returns:
[
{
"pic": "",
"_id": "623ad5c75d17751ff664a9ae",
"organizationId": "6239b5fc3c16a8041341a3e8",
"roleId": "ba3e35fc1341a80462c16398",
"projectsId": [
"6239b61f8f8e67d675297178",
"6239b637a4ec3ff5ef2df0cb"
],
"email": "yosephten#gmail.com",
"password": "$2a$10$hIMWjl2wz9g1C3NN4sqwHOMgx0epaJtdOmGVWckkRcCqltIn9JlTe",
"createdOn": "2022-03-23T10:42:11.170Z"
}
]
I tried it in mongoDB locally by running the same code: db.users.find({organizationId: '6239b5fc3c16a8041341a3e8'}) but this time, it returns the specified user.
I don't know if it is the capitalization or mongoose the issue. Please help.
Thanks.
Found it.
The issue was when i was creating users in db, i was using this script:
db.users.insertMany([
{
'organizationId': '3c16a8046239b5fc1341a3e8',
'roleId': 'ba3e35fc1341a80462c16398',
'email': 'yosephten#gmail.com',
'password': '$2a$10$hIMWjl2wz9g1C3NN4sqwHOMgx0epaJtdOmGVWckkRcCqltIn9JlTe'
},
{
'organizationId': 'b5fc3c16a80462391341a3e8',
'roleId': 'ba3e35fc1341a80462c16398',
'email': 'yoseph2#gmail.com',
'password': '$2a$10$hIMWjl2wz9g1C3NN4sqwHOMgx0epaJtdOmGVWckkRcCqltIn9JlTe'
},
])
But this will make the foreign key fields(organizationId roleId and projectsId) strings. Thus failing the check.
The script should be:
db.users.insertMany([
{
'organizationId': new ObjectId('3c16a8046239b5fc1341a3e8'),
'roleId': new ObjectId('ba3e35fc1341a80462c16398'),
'email': 'yosephten#gmail.com',
'password': '$2a$10$hIMWjl2wz9g1C3NN4sqwHOMgx0epaJtdOmGVWckkRcCqltIn9JlTe'
},
{
'organizationId': new ObjectId('b5fc3c16a80462391341a3e8'),
'roleId': new ObjectId('ba3e35fc1341a80462c16398'),
'email': 'yoseph2#gmail.com',
'password': '$2a$10$hIMWjl2wz9g1C3NN4sqwHOMgx0epaJtdOmGVWckkRcCqltIn9JlTe'
},
])
Now mongoose will check ObjectId to ObjectId instead of ObjectId to String.
Related
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 }
)
I have this model.
User.js
methods: {
type: [String],
required: true,
},
local: {
email: {
type: String,
lowercase: true,
},
password: {
type: String,
},
id: Number,
title: {
type: String,
enum: ['Ms', 'Mrs', 'Mr', 'Dr'],
default: 'Mr',
},
firstName: String,
lastName: String,
role: {
type: String,
default: 'user',
},
permissions: [String],
},
status: { type: Boolean, default: true },
Please note that local field has many properties.
Say I only want to update few properties. namely title,lastName and role.
{
lastName:'virat',
role:'manager',
title:'Mr'
}
I tried to update it like this
const filter = { _id: req.params.id };
const update = {
local: {
lastName: "virat",
role: "manager",
title: "Mr",
},
};
await User.findOneAndUpdate(filter, update);
After the update, local has only 3 fields and other fields have been gone.
How do I update certain fields without losing the other fields?
Any help!
Thanks in advance! =)
Try this:
const filter = { _id: req.params.id };
const update = {
"local.lastName": "virat",
"local.role": "manager",
"local.title": "Mr"
};
await User.findOneAndUpdate(filter, update);
I'm trying to have each record attached to a user who created it,
and every user have their records attached.
Here are my schemas:
1.The Records schema:
const mongoose = require('mongoose')
const RecordsSchema = new mongoose.Schema(
{
Title: { type: String, required: true },
postedby:[{
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
}],
Author: { type: String, required: true},
ISBN: { type: String, required: true },
Review: { type: String },
SelectedFile: { type: String },
Likes: { type: Number, default:0},
Date: { type: Date, default: Date.now()}
});
module.exports = Records = mongoose.model('record', RecordsSchema', 'record');`
Here is the The user Schema:
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema(
{
username: { type: String},
email: { type: String, required: true ,unique:true},
records:[{
type: [mongoose.Schema.Types.ObjectId],
ref: 'record' }],
password: { type: String, required: true},
Date: { type: Date, default: Date.now(), immutable: true }
});
module.exports = User = mongoose.model('user', userSchema,'user');
The express route for getting a record:
router.get('/postedby/', (req, res) => {
Records.find(req.params.id)
.populate('postedby')
.exec()
.then(post =>{
if (!post) {
return res.status(400).json({ msg: 'Add Posts' });
}
else return res.json(post);
}).catch (err => console.error(err))
});
Result of the route:
{
"postedby": [],
"Likes": 0,
"_id": "5fed8c12a4fb2c1e98ef09f6",
"Title": "New Age",
"Author": "Situma Prisco",
"ISBN": "23422",
"SelectedFile": "",
"Review": "",
"Date": "2020-12-31T08:30:10.321Z",
"__v": 0
},
I'm getting a blank Array on the populated user field(posteddby) .
Please help, What am I doing wrong? And yes, i do have a User Logged in
You are too close.
In your schema definition, postedby field itself is an array. Hence you can simply define it like :
postedby:[{
type: mongoose.Schema.Types.ObjectId,
ref: 'user'
}]
Make sure that the ObjectID is stored properly in the postedby array.
Also, you are trying to find a single record based on the ID, hence you can use findById(req.params.id) or findOne({_id:req.params.id}) which would return a single document.
I am attempting to findOneAndUpdatea string-based token on a User model. And
I receive the error:
Cast to ObjectId failed for value "{ passwordResetToken: '4946d72f19b9649d3f306a0f5be59005c884ae453fc049c7',
passwordResetExpires: { '$gt': 1543196590882 } }" at path "_id" for model "User"
the document is stored like so:
{
"_id": {
"$oid": "5bfb424da0cc0923f05b67f1"
},
"local": {
"email": "XXXXXXXXXXXXXXXXX",
"password": "XXXXXXXXXXXXXXXXX"
},
"isVerified": false,
"method": "local",
"__v": 0,
"passwordResetExpires": {
"$date": "2018-11-26T02:41:17.851Z"
},
"passwordResetToken": "4946d72f19b9649d3f306a0f5be59005c884ae453fc049c7"
}
and I query the document like so:
req.params.token = "4946d72f19b9649d3f306a0f5be59005c884ae453fc049c7"
User.findByIdAndUpdate({
'passwordResetToken': req.params.token,
'passwordResetExpires': { $gt: Date.now() }
},
{
'local.password' : req.body.password,
'passwordResetExpires' : null,
'passwordResetToken' : null
}, {new: true})
.then(user => {
res.send(user);
})
.catch(err => next(err))
This is my current Schema:
var userSchema = mongoose.Schema({
method: {
type: String,
enum: ['local', 'google', 'facebook']
},
local: {
email: {
type: String,
lowercase: true
},
password: String,
},
google: {
id: String,
email: {
type: String,
lowercase: true
},
name: String,
token: String
},
facebook: {
id: String,
name: String,
token: String
},
isVerified: {
type: Boolean,
default: false,
required: true
},
passwordResetToken: String,
passwordResetExpires: Date
});
I guess mongoose Is attempting to cast this hex string into a _id value? Is there some way to prevent mongoose from casting the string into an ObjectId Type?
In mongoose, if you use findByIdAndUpdate(), you have to provide a value that is the objectID. So, in your case, it tries to find an Object ID but cannot and hence you get an error. Something more appropriate to your use case would be findOneAndUpdate(). Here, you are free to use other parameters.
Having trouble with the following schema
const FriendRequestSchema = new Schema({
requester: {
_id: {
type: Schema.Types.ObjectId
}
},
profilePicture: String,
pending: {
type: Boolean,
default: true
}
})
the way i create a new friend request
const friendRequest = new FriendRequest({
requester: {
_id: req.user._id
},
profilePicture: req.user.profilePicture
})
results object
{
"pending": true,
"_id": {
"$oid": "5ab4fdb07525fd6880d1a6b9"
},
"profilePicture": "/assets/profile_icons/glasses.png"
}
now the problem is:
im missing the requester field
the id field is always different and dosent save the requester id
how can i fix this ?
Try change you schema like this:
requester: {
type: Schema.Types.ObjectId,
required: true,
ref: 'User', // depends on how you called user schema
},
Usage:
const friendRequest = new FriendRequest({
requester: req.user._id,
profilePicture: req.user.profilePicture
})