There is a strange document in our production database, which isn't possible to find itself. This was tried with mongodb version 2.4 and 2.6.
With mongojs
it can be reproduced with the following code
var mongojs = require('mongojs');
// production is the name of my local production database copy
var db = mongojs('production', ['settings']);
var raise = function(err) {
if(err) throw err;
};
// This is the actual id of the document in the production database
var id = new mongojs.ObjectId('5158a0272f191a8d64ec25d3');
db.settings.findOne({ _id: id }, function(err, setting) {
raise(err);
if(!setting) raise(new Error('Setting missing'));
db.settings.findOne(setting, function(err, self) {
raise(err);
console.log(self); // <-- self is null
});
});
Doing the equivalent queries in the mongodb shell actually finds the document.
// self.js
var id = ObjectId("5158a0272f191a8d64ec25d3");
var setting = db.settings.findOne({ _id: id });
var self = db.settings.findOne(setting);
print(tojson(self)); // <-- self is the correct object
It can be run with the following command. production
refers to the database name (can be an URL to a mongohq database).
$mongo production ./self.js
But if we use the shell to first store the document in a file and use that file to find the document it fails.
First save the document
// self.js
var id = ObjectId("5158a0272f191a8d64ec25d3");
var setting = db.settings.findOne(setting);
print(tojson(setting));
And run it with
$mongo production ./self.js > doc.js
doc.js
content should be something like
MongoDB shell version: 2.6.1
connecting to: production
{
"_id" : ObjectId("5158a0272f191a8d64ec25d3"),
...
}
Delete the first two lines and declare the object in a variable, so it ends up looking like
var s = {
"_id" : ObjectId("5158a0272f191a8d64ec25d3"),
...
}
Now in a new mongo shell script file, we load the file and try to fetch the document from the database. But null
is returned.
load('./doc.js');
var self = db.settings.findOne(s);
print(tojson(self)); // <-- self is null
There doesn't seem to be a problem using the ruby
driver for mongo.
Copying the document first (both using mongojs
and the shell
) "fixes" the document, so it can find itself.
Possible problems
- There are decimals numbers in the document. May be some kind of rounding error when serializing and again loading the document.
- Weird unicode characters in strings. Some of the property names in the document are user defined, there could be some characters which are lost during serialization.
I've tried to investigate both of these, by removing properties containing numbers and strings, but couldn't come to a definite conclusion.
The following seems to be the minimal document for which this bug is visible (it was obtained by removing properties one by one from the original). Furthermore it seems to be caused by the two last objects (5497017302350460 and 72135999), if they are both present it fails, but if one of them is removed the query succedes.
{
"_id" : ObjectId("5158a0272f191a8d64ec25d3"),
"bankAccounts" : {
"38216677" : {
},
"5497017302350460" : {
},
"72135999" : {
}
}
}
production.zip contains a mongodump
of the document.