Reputation: 1666
I've seen this question asked here, but none of the answers ever worked for me.
My code:
var BSON = require('mongodb').BSONPure;
// value is 544d644cf6eea12336f5e0a1
var object_id = BSON.ObjectID.createFromHexString(req.params.id);
}
// Create GET _id query
collection.find(object_id).toArray(
function (err, data) {
if (!err) {
// 200 OK
return res.status(200).send({success: true, code: 200, count: data.length, results: data});
} else {
// 500 Internal Server (Mongodb)
console.log(err);
return res.status(500).send({success: false, code: 500, error: "Internal Server Error"});
}
I've tried about five different ways to find by ObjectId and none have worked. Above is my latest attempt. I get no results back from Node. Inside the mongo shell when I do:
> db.people.find({_id : ObjectId("544d644cf6eea12336f5e0a1")});
{ "_id" : ObjectId("544d644cf6eea12336f5e0a1"), "name" : "Jim", "age" : 24, "job" : "engineer" }
As you can see I get a result. What am I missing here?
Upvotes: 3
Views: 3308
Reputation: 1666
I upvoted all your answers. Within the context of my original question, all of your answers were correct. Thanks for the help! The issue was something different entirely, which I won't bore you with unless you really want to be bored...
Well, ok. My app builds routes dynamically from a Mongo collection. In order for the loop that iterates through this list of routes to actually work, there must be a self invoking function enclosing the route creation logic, eg:
for (var route in collections) {
(function () {
// Set vars
var collection = db.collection(collections[route]);
// Create Express GET route
app.get('/' + collections[route] + '/:id', function (req, res) {
// Return 400 Bad Request error if no params provided
if (typeof req.params.id == 'undefined') {
return res.status(400).send({
success: false,
code: 400,
error: "No _id parameter provided"
});
}
// Create GET _id query
collection.find({_id: new ObjectId(req.params.id)}).toArray(function (err, data) {
if (!err) {
// 200 OK
return res.status(200).send({
success: true,
code: 200,
count: data.length,
results: data[0]
});
} else {
// 500 Internal Server (Mongodb) Error
console.log(err);
return res.status(500).send({
success: false,
code: 500,
error: "Internal Server Error"
});
}
});
});
}
}
When this self invoking anonymous function isn't there to enclose the logic, the router just uses whatever the last value of collections[route] was, so a call to /accounts/:id will field the request (because the route does exist), but it will actually point to the people collection in Mongo because that was the last value in the array (because it wasn't forced to be evaluated when the loop was originally run). I hope this explanation makes sense. At any rate, my bad for forgetting to use (function(){})();
Upvotes: 0
Reputation: 51440
Compare the ways you're querying your collection in MongoDB shell and in node.js.
In MongoDB shell your query looks like
{_id : ObjectId("544d644cf6eea12336f5e0a1")}
but in node.js it's just
ObjectId("544d644cf6eea12336f5e0a1")
Please, try the following code:
var ObjectID = require('mongodb').ObjectID;
// ...
collection.find({_id : ObjectId("544d644cf6eea12336f5e0a1")}).toArray(function (err, data) {
// data[0] is your document here
}
If you have troubles using node-mongodb-native
, try mongojs instead. It's built on top of node-mongodb-native
and designed to emulate MongoDB shell as much as possible.
Upvotes: 3
Reputation: 1155
Same as in mongo shell, you need to compose a query object for find(). Here is the example:
var mongodb = require('mongodb');
var MongoClient = mongodb.MongoClient;
var ObjectId = mongodb.ObjectID;
MongoClient.connect('mongodb://localhost:27017/test', function(err, db) {
db.collection('people', function(err, collection) {
collection.find({_id: new ObjectId('544d644cf6eea12336f5e0a1')}).toArray(function(err, docs) {
console.log(docs);
db.close();
});
});
});
You might also want to review related documentation for find() and ObjectID
Upvotes: 8