Reputation: 6943
I am working with Node.js to build a web socket server that uses mongodb.
I am using node-mongodb-native as the library to access mongo db.
When I call console.log(sys.inspect(item)) on an object from the db I get something that looks like this:
{ _id: { id: 'L?#&\u008e\u00ad\u000e\u008f\u0014\u0005\u0000\u0000' }
, y: 3
, favorite_color: 'orange'
, x: 14766
}
so I am guessing the id is the BSON object id that mongo uses.
I need to send this object to the client web browser using JSON, have them do some stuff to it, and then send it back to the server.
When I JSON.stringify(item), I get something that looks like this:
{"_id":"4c3f23268ead0e8f14050000","y":3,"favorite_color":"orange","x":14766}
So the id has been turned into some hex encoded string. If I send it to the client, and the client sends it back, I now need to update it in the db. I run JSON.parse(item) to get it to be a normal object, but it still looks like this:
{ _id: '4c3f23268ead0e8f14050000'
, y: 3
, favorite_color: 'orange'
, x: 14766
}
and that _id can't be used to look up in mongodb.
How can I convert it back to a format that will be able to be used for lookups on mongo?
--update--
Interestingly I can use findOne({_id:item._id}, collection)
to get the document, but if I do this:
findOne({_id:{id : item._id.id}}, collection)
I don't receive a result. I guess there is something special about the mongo _id object.
Both {_id:item._id}
and {_id:{id : item._id.id}}
when dumped out look like this:
{ _id: { id: 'L?#&\u008e\u00ad\u000e\u008f\u0014\u0005\u0000\u0000' } }
--Another update RESOLVED---
There was some object id manipulation in an integration test file.
objectId = new mongo.ObjectID.createFromHexString('47cc67093475061e3d95369d'); will give the _id that I am looking for.
objectId.toHexString() will return the hex string that looks like '47cc67093475061e3d95369d'
Upvotes: 2
Views: 9358
Reputation: 1920
Well, I was stuck with the same error while working with python client. But I will clarify the accomplishment result for both languages.
Firstly the _id
MongoDB returns is the BSON object. Meaning binary-encoded serializationfor of JSON, more in this link: BSON
Let's say you want to insert data with the following fields:
params = {
"y":3,
"favorite_color":"orange",
"x":14766
}
client.connect(url, function(err, db) {
var dbo = db.db("test_database");
dbo.collection("my_collection").insertOne(params, function(err, res) {
if (err) throw err;
console.log("inserted document",JSON.stringify(res));
db.close();
});
});
it return object result, for instance "_id":"5e95abf57b59b448bb22dedf"
Defining ObjectId, you can easily use findOne, updateOne methods.
const {ObjectId} = require('mongodb');
client.connect(url, function(err, db) {
var dbo = db.db("test_database");
var myquery = { "_id": ObjectId("5e95abf57b59b448bb22dedf") } ;
dbo.collection("my_collection").findOne(myquery, function(err, result) {
if (err) throw err;
console.log(result);
});
});
update:
client.connect(url, function(err, db) {
var dbo = db.db("test_database");
var myquery = { "_id": ObjectId("5e95abf57b59b448bb22dedf") } ;
var newvalues = { $set: {favorite_color: "red", y: "14760" } };
dbo.collection("my_collection").updateOne(myquery, newvalues, function(err, res) {
if (err) throw err;
console.log("1 document updated");
db.close();
});
});
For python:
let's take this result as an example: {'_id':ObjectId('5e95a18dcae4a4a005e14bd8')}
from bson.json_util import loads as bson_loads, dumps as bson_dumps
import json
#you should dump it then load it
result = document = json.loads(bson_dumps(document))
{ "$set": {"status": False}}
#update:
db["my_collection"].update_one({ "_id": result},new_value)
#find_one:
db["my_collection"].find_one({ "_id": resultjs})
For more to work with python MongoDB client(motor) I have created Gist
Upvotes: 0
Reputation: 32184
My guess is that sys.inspect
interprets an ObjectId as an object containing an id
property. That's what you're seeing in the dump.
MongoDB treats the ObjectId as a 12-byte binary value, not as an object. So MongoDB doesn't know about any id
property. That's why the following query yields no result:
findOne({_id: {id: item._id.id}}, collection)
The following does work, as it just treats both values as binary values:
findOne({_id: item._id}, collection)
Upvotes: 1