Configuration: Mongoose 4.0.5, MongoDb 3.0.4, Node 0.12.4
Issue does not appear on Mongoose 3.8.30
My database has the following data:
db.users.find()
{ "_id" : ObjectId("5580c79aa11e7310b2985ab1"), "email" : "an_email", "color" : "", "username" : "", "__v" : 0 }
I query it with Mongoose using the following syntax:
User.findById("5580c79aa11e7310b2985ab1", function(error, user) { }
which returns null for both error and user. Strangely enough Mongoose's debugging shows the following, correct query:
users.findOne({ _id: ObjectId("5580c79aa11e7310b2985ab1") })
which queried directly on MongoDB finds the expected data:
db.users.findOne({ _id: new ObjectId("5580c79aa11e7310b2985ab1") })
{
"_id" : ObjectId("5580c79aa11e7310b2985ab1"),
"email" : "an_email",
"color" : "",
"username" : "",
"__v" : 0
}
I tried various alternatives such as directly initializing an ObjectId object or taking an ObjectId from a find()
result which leads to no results either. As stated above reverting back to Mongoose 3.8 resolves the issue.
Hmm can you show me your schema? Also, do you have mongodb or bson installed as peer dependencies?
My schema:
var userSchema = new Schema({
username: { type: String, required: false },
email: { type: String, required: true, index: { unique: true } },
color: { type: String, required: false }
});
userSchema.statics.createOrUpdateUser = function(email, username, color, newEmail, callback) {
// excluded
};
userSchema.virtual('md5').get(function () {
// excluded
});
var User = db.model('User', userSchema);
Neither MongoDb nor bson are co-dependencies but I do have connect-mongostore
which includes mongodb as one of their sub-depedencies.
I am also having this issue in version 4.0.2+.
Latest version where this problem does not appear is 4.0.1.
@nafisto please provide repro instructions for your particular case
@vkarpov15 Here you go...
var userSchema = mongoose.Schema({
email: { type: String },
passwordEnc: { value : String, version: String, salt : String },
nameFirst : String,
nameLast : String,
phone : String,
dob : String
});
var User = mongoose.model('User', userSchema);
User.find({}); // returns array of all users
User.find({ nameFirst: 'John' }); // returns array of users named John
User.findOne({ nameFirst: 'John' }); // returns first user named John
User.find({ _id: ObjectId('55822f34a8394683dd015888'); // returns empty array
User.findOne({ _id: ObjectId('55822f34a8394683dd015888'); // returns null
(Fails on MongoDB v2.6.4, NodeJS v0.10.31 with Mongoose versions 4.0.2, 4.0.3, 4.0.4, 4.0.5)
Where do you get the ObjectId
function from in that example?
Aw sorry, copy-paste error from a test I ran at the command line. Should be this:
User.find({ _id: '55822f34a8394683dd015888' }); // returns empty array
User.findOne({ _id: '55822f34a8394683dd015888' }); // returns null
I started experiencing this issue today, exactly as described by @florianheinemann, both on versions 4.0.5 and on 4.0.2 when tried to roll back.
@vkarpov15, to your question I used mongoose constructor to get the Id:
var mongoose = require('mongoose');
var id = new mongoose.Types.ObjectId(stringId);
I also noticed that when pulling the document by other functions that work (and not by using findById or and other find with _id on the query, the _doc object didn't have any _id property.
@nafisto - thanks for sharing the insight about 4.0.1.
Rolled back to 4.0.1 and now it's working again.
@nafisto the below script works fine for me on 4.0.5:
var assert = require('assert');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.set('debug', true);
mongoose.connect('mongodb://localhost:27017/gh3078');
var userSchema = mongoose.Schema({
email: { type: String },
passwordEnc: { value : String, version: String, salt : String },
nameFirst : String,
nameLast : String,
phone : String,
dob : String
});
var User = mongoose.model('User', userSchema);
User.remove({}, function(error) {
assert.ifError(error);
User.create({ _id: '55822f34a8394683dd015888', dob: 'test' }, function(error) {
assert.ifError(error);
User.findById('55822f34a8394683dd015888', function(error, doc) {
assert.ifError(error);
assert.ok(doc);
console.log(JSON.stringify(doc));
console.log('done');
process.exit(0);
});
});
});
Can you verify the above script works for you? Also, can you provide me the output of npm list | grep "mongo"
so I can see what your setup for mongodb packages is like?
@florianheinemann the below script works for me:
var assert = require('assert');
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.set('debug', true);
mongoose.connect('mongodb://localhost:27017/gh3079');
var userSchema = new Schema({
username: { type: String, required: false },
email: { type: String, required: true, index: { unique: true } },
color: { type: String, required: false }
});
userSchema.virtual('md5').get(function () {
// excluded
});
var User = mongoose.model('User', userSchema);
var obj = { "_id" : "5580c79aa11e7310b2985ab1", "email" : "an_email", "color" : "", "username" : "", "__v" : 0 };
User.remove({}, function(error) {
assert.ifError(error);
User.create(obj, function(error) {
assert.ifError(error);
User.findById('5580c79aa11e7310b2985ab1', function(error, doc) {
assert.ifError(error);
assert.ok(doc);
console.log(JSON.stringify(doc));
process.exit(0);
});
});
});
Can you verify the above script works for you? Also, can you provide me the output of npm list | grep "mongo" so I can see what your setup for mongodb packages is like? Also, how are you connecting to mongodb, e.g. what does your call to mongoose.createConnection()
look like?
Yes, that works for me:
Mongoose: users.ensureIndex({ email: 1 }) { unique: true, background: true, safe: undefined }
Mongoose: users.remove({}) {}
Mongoose: users.insert({ _id: ObjectId("5580c79aa11e7310b2985ab1"), email: 'an_email', color: '', username: '', __v: 0 })
Mongoose: users.findOne({ _id: ObjectId("5580c79aa11e7310b2985ab1") }) { fields: undefined }
{"_id":"5580c79aa11e7310b2985ab1","email":"an_email","color":"","username":"","__v":0}
I'll have to come back to you on the other ones as I'm right now busy with other stuff...
Thanks, that would be great. Sorry for the delay in getting back to you, I was on vacation. Any help would be much appreciated - multiple people have run into this issue but I haven't been able to spot how its happening.
Hey,
So, I reverted back to Mongoose 4.0.5 and have the same issues again (but it works with the exact same code on 4.0.7). Here the requested info:
npm list | grep "mongo"
βββ¬ [email protected]
β βββ¬ [email protected]
βββ¬ [email protected]
β βββ¬ [email protected]
β β βββ¬ [email protected]
βββ¬ [email protected]
β βββ¬ [email protected]
β β βββ¬ [email protected]
My connection:
mongoose.connect("mongodb://127.0.0.1:27017/wwwpasswordlessnet", { server: { auto_reconnect: true } });
Hmm nothing looks out of the ordinary. Where are you getting the id from? Are you passing it as a literal string or are you getting it from one of the *-mongostore modules?
Ok, I've now cut almost everything out of my script to be similar to yours. What I notice is that my script results in the following:
> db.users.find({email: 'test'})
{ "_id" : { "_bsontype" : "ObjectID", "id" : "UΒ₯\u0019ΒΌxΓΒA>qPO", "generationTime" : 1436883388 }, "email" : "test", "__v" : 0 }
while yours results in:
> db.users.find({email: 'test'})
{ "_id" : ObjectId("55a51a6765fb1a473f01ee43"), "email" : "test", "__v" : 0 }
I even require the exact same model. It is as if Mongoose would now from which file it is called. I'm at a complete loss here. The only other difference (except the file it's called from) is that my script is called from within an Express middleware. And also: It works with Mongoose 4.0.7
That's really strange. The only way I can imagine that happening is that you're creating a new ObjectId using one of the mongostore modules and trying to save it into mongoose. Can you show me what your express middleware looks like?
This issue is stale and haven't been able to repro. Looks like it might have been already fixed. Re-open if this is still an issue.
I experienced this error yesterday, in my case error was caused by data imported to mongo. After I used mongoimport key _id was stored as string instead of ObjectId. When I was quering data in mongo everything works well, but in Mongoose when I was trying find something by _id it always returned null or empty Array. I hope that info might by useful for someone.
I was having very same issue as @florianheinemann and @nafisto . The strange thing was that I could use find
and findById
on other models without any problem. Finally I managed to found out that mongoose uses my collection User
as users
. It is lowercasing and adding s to the end (They say that this behaviour is smart). Anyway I had to force collection name to model and schema as shown below in bold. That fixed the issue for me.
var userSchema = mongoose.Schema({
email: { type: String },
passwordEnc: { value : String, version: String, salt : String },
nameFirst : String,
nameLast : String,
phone : String,
dob : String
},{collection: 'User'});
var User = mongoose.model('User', userSchema, 'User');
I am having this issue in May 2016
[~/dev/rikai/boteditor]$ npm list | grep mon *[mongoose-merge]
βββ¬ [email protected]
β βββ¬ [email protected]
βββ¬ [email protected]
β βββ¬ [email protected]
β β βββ¬ [email protected]
some of the data was created outside of Mongoose.
code sample please
@dcsan I had the same issue trying to convert a sailsjs app to mongoose. This was because sails creates a singular collection name where Mongoose creates a plural collection name. So might be worth checking that. If it is the case you can then set the collection name on your schema.
for me the issue was related to a data migration, and the original data was using strings that looked like ObjectIDs.
I've got same issue, i resolved changing the name of collection. Thank you @skecskes
Hi,
I am having similar issue. I am trying to find record in mongo and I am using nodejs and trying findById and it returns null to me while direct query on mongo returns me record. Strange thing for me is it is happening for few records only. i can not differentiate between the records. I tried adding collection in model and also changing by collection name but none worked.
below is code snippet:
if (req.params.timeId) {
Time.findById(req.params.timeId).exec(function (err, time) {
console.log('Time I see :', time);
});
The above code is working for some timeid (which is _id of time table).
Check in mongodb and make sure that your time _id
fields are all ObjectIds rather than plain strings
mongoose = require('mongoose').set('debug', true);
Use this so you can see what query mongoose are sending to the database. It helped me when I had the same problem as you. In my case, mongoose was sending the collection name in plural.
thanks JonatasCV, that "debug" option saved my day
Kindly check your url it should not be the same with other get method
app.get('/somthinghere/:id', function(req, res){
...
}
I had a similar issue today. It turns out i saved an _id as a ObjectId string and tried to retrieve id using the object ObjectId(id).
I tested the vice versa situation where an _id is saved as an ObjectId instance and retrieving it as a string.
They both do not return data when calling findOnce and no error message
thanks @JonatasCV the debugging return findOne query mothod instead of findOneById and also bypasses null in the id field .
Debugging result =>> Mongoose: books.findOne({ _id: null }, { fields: {} })
// Book Schema
const bookSchema = mongoose.Schema({
title:{
type: String,
required: true
},
genre:{
type: String,
required: true
},
description:{
type: String
},
author:{
type: String,
required: true
},
publisher:{
type: String
},
pages:{
type: String
},
image_url:{
type: String
},
buy_url:{
type: String
},
create_date:{
type: Date,
default: Date.now
}
});
// Get Book
module.exports.getBookById= function(id,callback){
Book.findById(id,callback);
}
I'm surprised this is still closed, but I ran into this issue again today. I fiddled with my code and installation for hours and what ended up working was my original code that was bugged. Not sure what the bug stems from, but it appears to be finicky.
Most helpful comment
mongoose = require('mongoose').set('debug', true);
Use this so you can see what query mongoose are sending to the database. It helped me when I had the same problem as you. In my case, mongoose was sending the collection name in plural.