Mongoose find all documents with a given ObjectId - node.js

I have a photo model and every photo has a vehicle associated with it:
var ObjectId = mongoose.Schema.ObjectId;
var photoSchema = mongoose.Schema({
name: { type: String},
path: { type: String},
vehicle: { type: ObjectId, ref: 'Vehicle' }
});
What query can I perform to return all photos that match a given vehicle _id? I think the query looks the same as a normal find, but I'm not sure how to turn an _id into an ObjectId.

You don't need to turn anything, your ObjectId itself is _id but in string format when you send it through JSON to somewhere. Try following:
Photo.find({vehicle: id}, function(err, result){...});
Above id is just your vehicle's ObjectId obtained from any source e.g. User Interface

Related

default value for ref collection in mongoose

I have a user profile, I have a field of 'earning' and it look like this in the schema
earning: {
type: Schema.Types.ObjectId,
ref: 'Earning'
}
This how do I make a default value for earning field when a new user is created? I can't do this
earning: {
type: Schema.Types.ObjectId,
ref: 'Earning',
default: 0
}
I got error of
Cast to ObjectId failed for value "0" at path "earning"
What you are doing wrong here is trying to cast a number on an ID field. Since it's a reference of another object Id field, you can not set 0 to it. What you need to do is to set null when a user is created in db and initialize it with a null value of earning.
Like:
earning: {
type: Schema.Types.ObjectId,
ref: 'Earning',
default: null
}
When instantiating a document based on a Schema which has a key of type 'ObjectId' and a ref to another collection, the only way that I've found to set a 'default' value is through the use of Mongoose middleware at the schema level as described here. For example, setting a comment's author to a default 'guest' document from a User collection when the author is not logged in might look like this:
// user document in MongoDB
{
_id: ObjectId('9182470ab9va89'),
name: 'guest'
}
// CommentSchema
const mongoose = require('mongoose')
const CommentSchema = mongoose.Schema({
author: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
body: String
})
CommentSchema.pre('save', function (next) {
this.author == null ? this.author = '9182470ab9va89' : null
next()
})
module.exports = mongoose.model('Comment', CommentSchema)
This example uses the 'save' pre hook with the ObjectId hardcoded in the schema for demonstration purposes, but you can replace the hardcoding of the ObjectId with a call to your backend or however else you'd like to get that value in there.
As I understand earning is indication of how much user earn so it should be of type Number not ObjectId
so try to change your Schema to be
earning: {
type: Number,
ref: 'Earning',
default: 0
}
so you can use 0
Note: if you should use ObjectId for some reason so the answer of 'Haroon Khan' is the correct answer.

Mongoose Populate Cast Error

I have the follwing schemas:
// online.js
var mongoose = require('mongoose');
// Online Friends
var onlineSchema = mongoose.Schema({
userid:{ type: Number, ref:'Player' }
},{timestamps : true});
// Export
module.exports = mongoose.model('Online', onlineSchema);
//player.js
var mongoose = require('mongoose');
// define the schema for player data
var playerSchema = mongoose.Schema({
userid : { type: Number, required: true,unique:true, default: 0 },
firstname : { type: String },
nick : {type: String, required: true},
lastname : {type: String},
lastupdate: {type: Date, default: Date.now}
},{timestamps : true});
// create the model and expose it to our app
module.exports = mongoose.model('Player', playerSchema);
//main.js
...
const Online = require('./config/models/online.js');
const Player = require('./config/models/player.js');
Online.find({userid:3441341}).populate('userid').exec(function(err,result){
if (err) {
console.log(err);
} else {
console.log(result);
}
});
...
I want to search Online for a userid and then print the name of the user, not exactly sure what I am doing wrong.
This is the error I'm getting:
MongooseError: Cast to ObjectId failed for value "3441341" at path "_id"
What is the proper way to achieve this ?
Change the userid type from Number to mongoose.Schema.ObjectId and it should work. It basically says you are trying to cast a number to Object Id. Pass the ids as strings.
In NoSQL DBS your documents must have _id field. Do you have a User model or do you use Player for the job? If you use Player as User model so change user_id to _id

How to populate mongoose models with other key without using _id(objectId) in ref

I am using MySQL data earlier. Now I am migrated to MongoDB. I want mongoose to populate some data. whereas I want to use my own key to populate in place of _id(objectId) in ref.
something like below.
Space schema
SpaceShema = mongoose.Schema({
id: Number,
cid: {
type: mongoose.Schema.Types.ObjectId,
ref: Client
},
space: String
});
I want to use id in ClientShema to populate in place of ObjectId
Below is the client schema
ClientShema = mongoose.Schema({
id: Number,
client: String,
});

save mongoose model and submodel after populate

I'm trying to find a way to simplify my backend logic and optimize my DB, for this it would be great if I could save a document and it's subdocuments all at once so that creating subdocuments becomes easier.
Here is a simple example:
the primary model:
var ItemSchema = new Schema({
name: {type : String},
extrainfo: {type: Schema.Types.ObjectId, ref: 'Extrainfo'},
})
mongoose.model('Item', ItemSchema);
the subdocument:
var ExtrainfoSchema = new Schema({
this: {type : String},
that: {type: String},
})
mongoose.model('Extrainfo', ExtrainfoSchema);
how I hoped to be able to save:
Item.findOne({ name: 'whatever' }).populate('extrainfo').exec(function (err, item) {
item.extrainfo.this = "something diferen" //some random change in subdocument
item.save(function(){console.log("yay")}
});
Is there a way to do this whithout having to save to the document and the subdocument individually ?
Is there a way to do this whithout having to save to the document and the subdocument individually ?
No. mongodb will write to one and only one collection during a given write operation, and mongoose doesn't have any feature as far as I know to provide a single-callback facility to write to multiple collections.

Mongoose populate return undefined

I'm currently trying to develop an app using mongo and node.js.
I am facing a problem when I want to build a query who use the populate option.
Here are my Schemas :
// Schema used by mongoose
var userSchema = new mongoose.Schema(
{
_id: mongoose.Schema.Types.ObjectId,
login: String,
password: String,
movies: [ { type: mongoose.Schema.Types.ObjectId, ref: movieModel} ],
admin: Boolean
},{ collection: "user" });
var movieSchema = new mongoose.Schema(
{
_id: mongoose.Schema.Types.ObjectId,
title: String,
}, { collection: "movie" });
As you can see, each user have an array of movies, this array contains valid ids of movies. What I want is to have the movies of an user. This is how I build my query :
var query = userModel.findOne({ login: req.session.user["login"] })
.populate("movies");
query.exec(function(err, user)
{
if (err)
throw err;
console.log(user.movies[0].title);
});
The query is executed successfully, but when I try to display the title of the first movie at the console.log line I got an error "TypeError: Cannot read property 'title' of undefined". I checked the documentation of mongoose and don't understand why I'm getting this error.
I would like to specify that my database contains valid data.
I put mongoose in debug mode, and this is the query that is executed :
Mongoose: user.findOne({ login: 'user' }) { fields: undefined }
Mongoose: user.find({ _id: { '$in': [ ObjectId("52e2a28949ad409834473e71"), ObjectId("52e2a28949ad409834473e79") ] } }) { fields: undefined }
The two ids on the second line are valid ids of movies. I would like to display their name.
Thanks a lot for your help.
What is the value of this: ref: movieModel?
movieModel would need to be set to the string like "Movie". See here for more information. It will need to match the identifier provided when you create the Movie model.
var Movie = mongoose.model('Movie', movieSchema);
So, you might have in a schema:
var userSchema = mongoose.Schema({
name: String,
favorite_movies: { type: Schema.Types.ObjectId, ref: 'Movie' }
});
var User = mongoose.model('User', userSchema);
I've used the string Movie in both the Schema definition and when creating the Movie type. They need to be exactly the same.
MongooseJs uses the string name of the Model to determine where to fetch the documents from when using ref and populate.
In the debug output, you can see how Mongoose is actually querying the wrong collection, as I'd expect it to be using movies.find to find the relevant Movie documents.

Resources