How to save populated Document? - mongodb

Is it possible to save a populated document?
I am trying to do:
var Group = new Db['Group']();
for (var i=0; i<50; i++)
Db.Members.push({ User: { _id: "521014731e27b1b008000002"}, pseudo: 'John' });
Group.save();
Schemas
var GroupSchemaModel = {
Members: [{
User: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
updated_at: { type: Date, required: true, default: Date.now }
}]
};
I get the error
{ message: 'Cast to ObjectId failed for value "[object Object]" at path "User"',
name: 'CastError',
type: 'ObjectId',
value: { _id: '521014731e27b1b008000002' },
path: 'User' }

This:
User: { type: mongoose.Schema.Types.ObjectId, ref: 'User' },
Tells mongoose that User field will be a collection of references of type ObjectId pointing to another collection.
You, on the other hand, are trying to insert an object there:
Db.Members.push({ User: { _id: "521014731e27b1b008000002"}, pseudo: 'John' });
Mongoose tries to cast it to ObjectId and fails. That's apart from the fact that pseudo field isn't in the group schema.
Try this instead:
Db.Members.push({User: mongoose.Types.ObjectId("521014731e27b1b008000002"), updated_at: whatever});

Related

mongoose: getting unknown objectId when stored string instead of objectId

According to me when i pushed 'ABC' instead of objectId, It should show some error like
Cast to ObjectId failed for value "ABC" at path "likes".
but when i print that updated data i saw some unknown objectId in likes array
My question is, what is that unknown objectId(6a61736f6e20626f75726e65) and why it is generated
automatically
User Model
new Schema({
name: { type: String,required:true},
}, { usePushEach: true ,timestamp:true});
Feed Model
new Schema({
user: { type: Types.ObjectId, ref: 'user', required: true },
name: { type: String,default:null, trim: true },
likes: [{ type : Types.ObjectId, ref: 'user',}],
}, { usePushEach: true ,timestamp:true});
In Feed Schema likes have reference to User Schema
var data = await feed.findByIdAndUpdate(
postId,
{
$push: { likes: 'ABC' }
}
);
if(data){
var data = await feed.findById(postId);
console.log(data.likes);//["6a61736f6e20626f75726e65"]
}
OutPut:
["6a61736f6e20626f75726e65"]
Since you are pushing a String in likes which is not an ObjectId, you are getting this error.
Your schema clearly states that likes is an array of ObjectId:
likes: [{ type : Types.ObjectId, ref: 'user'}],
so you have to pass an ObjectId instead of user's name.
You have to do this:
// Whenever you are pushing value in `likes` `array`,
// you need to get the `ObjectId` of the user who liked the feed.
let userId = <userId_of_Ishwar>;
var data = await feed.findByIdAndUpdate(
postId,
{
$push: { likes: userId }
});

GraphQL Mutation Updating Users Followers with Mongoose/MongodDB - $set is empty error

I have this mutation set up:
followUser: {
type: UserType,
args: {
_id: { type: GraphQLString },
firebaseUid: { type: GraphQLString },
following: { type: new GraphQLList(GraphQLString)},
},
resolve(parentValue, { firebaseUid, _id, following}) {
const update = {
$set: { "following": [firebaseUid] },
$push: { "following": { firebaseUid } }
}
return UserSchema.findOneAndUpdate(
{ _id },
update,
{new: true, upsert: true}
)
}
},
I'm trying to add new followers into my graphql user's collection. My user model:
const UserSchema = new Schema(
{
firebaseUid: String,
following: [{ type: Schema.Types.ObjectId, ref: 'User' }],
followers: [{ type: Schema.Types.ObjectId, ref: 'User' }],
},
{ timestamps: true }
);
module.exports = mongoose.model("User", UserSchema);
So at first, the user doesn't have any followers, so it won't have that field yet. When user adds someone to their friends list, thats when the field will appear in mongodb. Right now I'm getting this error:
"message": "'$set' is empty. You must specify a field like so: {$set: {<field>: ...}}",
I'm not sure if I'm doing the $set correctly.
The UserType
const UserType = new GraphQLObjectType({
name: "User",
fields: () => ({
_id: { type: GraphQLString },
firebaseUid: { type: GraphQLString },
following: { type: new GraphQLList(GraphQLString) },
followers: { type: new GraphQLList(GraphQLString) },
...
})
});
edit:
current mongodb data collection:
_id: ObjectId("5e5c24111c9d4400006d0001")
name: "Mr. Smith"
username: "mrsmith"
after running the update
_id: ObjectId("5e5c24111c9d4400006d0001")
name: "Mr. Smith"
username: "mrsmith"
following: ["fdsaduybfeaf323dfa"] // <-- this gets added
Currently mongooses validator is rejecting the update. To fix this you need the following:
You only need to $push since it will automatically create an array if the property does not exist
You should remove the extra { } around the firebaseUid in the $push because otherwise the following array will contain objects with a firebaseUid property instead of directly containing the Uid (or would if the schema validator allowed it)
Mongo ObjectIds can only be converted from strings when they are 12-byte hexadecimal, and firebaseUid is not, so the schema should be typed to String instead of ObjectId as the validator will reject the field for update otherwise.

Mongo find users that are not blocked

I have a db in Mongo with users. I want to retrieve all user that are not in my blocked Array. tried to filter through the results by retrieving All documents but I wonder if that's the most efficient way. Is there a way in Mongo to find all users that are not part of an array?
Here is my User model:
var UserSchema = mongoose.Schema({
username: {
type: String,
index:true,
unique: true
},
password: {
type: String
},
email: {
type: String,
unique: true
},
name: {
type: String
},
latitude:{
type: String
},
longitude:{
type: String
},
blocked:{
type: Array
},
friends:{
type: Array
},
photo:{
type: String
},
identity:{
type: String
},
age:{
type: String
},
herefor:{
type: String
},
conns:{
type: Number
},
status:{
type: String
}
}, { collection: 'users' });
You are probably looking for something like the following, assuming your blocked users array contains usernames and your mongoose model is called UserModel:
var blockedUsernamesArray = [];
UserModel.find({ username: { $nin: blockedUsernamesArray } }, function(err, docs) {
// Handle result
})

MongooseError: Cannot read property 'options' of undefined when setting reference

Trying to set a simple reference field in Mongoose is giving me huge problems.
I get the following error. As far as I can tell there are no actual validation errors.
'contents.0.modules.0.matches.0.':
{ MongooseError: Cannot read property 'options' of undefined
at ValidatorError (C:\Users\Simon\Documents\Projects\eventvods\node_modules\mongoose\lib\error\validator.js:24:11)
at _init (C:\Users\Simon\Documents\Projects\eventvods\node_modules\mongoose\lib\document.js:372:37)
...
at init (C:\Users\Simon\Documents\Projects\eventvods\node_modules\mongoose\lib\document.js:348:7)
at model.Document.init (C:\Users\Simon\Documents\Projects\eventvods\node_modules\mongoose\lib\document.js:313:3)
message: 'Cannot read property \'options\' of undefined',
name: 'ValidatorError',
properties: [Object],
kind: 'cast',
path: undefined,
value: undefined } } }
Mongoose schema like so
var matchSchema = new Schema({
team1: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Teams'
},
team2: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Teams'
},
team1_2: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Teams'
},
team2_2: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Teams'
},
...
});
var moduleSchema = new Schema({
matches: [matchSchema],
...
});
var sectionSchema = new Schema({
modules: [moduleSchema],
...
});
A sample object that fails to save:
{
team1: 5835a5f653d4ce23bb33ab19,
team2: 5835a70353d4ce23bb33ab21
}
So this was a weird one, but I was able to bypass it with a little awkward manipulation.
Creating a new schema field of the same type, and setting that to
the value.
Going through all my documents, and setting the
original field to that field's value.
this is your team1 definition:
team1: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Teams'
}
and this is your data in mongo:
team1: 5835a5f653d4ce23bb33ab19
As you can see, team1 object type is not ObjectId! it's just a normal String!
Mongo stores a reference like this:
team1: {
"$ref" : "Teams",
"$id" : ObjectId("5835a5f653d4ce23bb33ab19")
}
So either fix your data in mongo or fix your scheme!
You have not defined your schema correctly. It should be more like so:
var matchSchema = new Schema({
team1: {
type: mongoose.Schema.Types.ObjectId,
ref: String
},
team2: {
type: mongoose.Schema.Types.ObjectId,
ref: String
},
team1_2: {
type: mongoose.Schema.Types.ObjectId,
ref: String
},
team2_2: {
type: mongoose.Schema.Types.ObjectId,
ref: String
},
...
});

Mongoose - using Populate on an array of ObjectId

I've got a schema that looks a bit like:
var conversationSchema = new Schema({
created: { type: Date, default: Date.now },
updated: { type: Date, default: Date.now },
recipients: { type: [Schema.ObjectId], ref: 'User' },
messages: [ conversationMessageSchema ]
});
So my recipients collection, is a collection of object id's referencing my user schema / collection.
I need to populate these on query, so i'm trying this:
Conversation.findOne({ _id: myConversationId})
.populate('user')
.run(function(err, conversation){
//do stuff
});
But obviously 'user' isn't populating...
Is there a way I can do this?
For anyone else coming across this question.. the OP's code has an error in the schema definition.. it should be:
var conversationSchema = new Schema({
created: { type: Date, default: Date.now },
updated: { type: Date, default: Date.now },
recipients: [{ type: Schema.ObjectId, ref: 'User' }],
messages: [ conversationMessageSchema ]
});
mongoose.model('Conversation', conversationSchema);
Use the name of the schema path instead of the collection name:
Conversation.findOne({ _id: myConversationId})
.populate('recipients') // <==
.exec(function(err, conversation){
//do stuff
});