16

I have a collection "companies" with several objects. Every object has "_id" parameter. I'm trying to get this parameter from db:

app.get('/companies/:id',function(req,res){
db.collection("companies",function(err,collection){
    console.log(req.params.id);
    collection.findOne({_id: req.params.id},function(err, doc) {
        if (doc){
            console.log(doc._id);
        } else {
            console.log('no data for this company');
        }
    });
});
});

So, I request companies/4fcfd7f246e1464d05000001 (4fcfd7f246e1464d05000001 is _id-parma of a object I need) and findOne returns nothing, that' why console.log('no data for this company'); executes.

I'm absolutely sure that I have an object with _id="4fcfd7f246e1464d05000001". What I'm doing wrong? Thanks!

However, I've just noticed that id is not a typical string field. That's what mViewer shows:

"_id": {
        "$oid": "4fcfd7f246e1464d05000001"
    },

Seems to be strange a bit...

f1nn
  • 6,989
  • 24
  • 69
  • 92

4 Answers4

21

You need to construct the ObjectID and not pass it in as a string. Something like this should work:

var BSON = require('mongodb').BSONPure;
var obj_id = BSON.ObjectID.createFromHexString("4fcfd7f246e1464d05000001");

Then, try using that in your find/findOne.

Edit: As pointed out by Ohad in the comments (thanks Ohad!), you can also use:

new require('mongodb').ObjectID(req.params.id)

Instead of createFromHexString as outlined above.

Community
  • 1
  • 1
Adam Comerford
  • 21,336
  • 4
  • 65
  • 85
  • I tried var obj_id = BSON.ObjectID.createFromHexString(req.params.id); collection.findOne({_id : obj_id},function(err, doc) { And it worked - thank you very much! – f1nn Jun 07 '12 at 10:15
  • 4
    You can use "new require('mongodb').ObjectID(req.params.id)" instead of createFromHexString – Ohad Kravchick Oct 24 '12 at 13:35
  • @OhadKravchick works like a charm. I would also up vote if it was an answer – Pith Jul 03 '13 at 09:29
3

That's because _id field in mongo isn't of string type (as your req.params.id). As suggested in other answers, you should explicitly convert it.

Try mongoskin, you could use it like node-mongodb-native driver, but with some sugar. For example:

// connect easier
var db = require('mongoskin').mongo.db('localhost:27017/testdb?auto_reconnect');

// collections
var companies = db.collection('companies');

// create object IDs
var oid = db.companies.id(req.params.id);

// some nice functions…
companies.findById();

//… and bindings
db.bind('companies', {
  top10: function(callback) {
    this.find({}, {limit: 10, sort: [['rating', -1]]).toArray(callback);
  } 
});

db.companies.top10(printTop10);
Aleksei Zabrodskii
  • 2,220
  • 3
  • 19
  • 41
1

You can use findById() which will take care of the id conversion for you.

company = Company.findById(req.params.id, function(err, company) {
    //////////
});
darren
  • 18,845
  • 17
  • 60
  • 79
  • 1
    What is Company in this case? What is findById? Can you link to the documentation? Thanks! – ryanm Sep 29 '15 at 15:44
0

In case these didn't work for you, this worked for me for accessing a blog post:

const getSinglePost = async (req, res) => {

    let id = req.params.id;
    var ObjectId = require('mongodb').ObjectId;
    const db = await client.db('CMS');

    const data = await db.collection("posts").findOne({ _id: ObjectId(id) })

    if (data) {
        res.status(200).send(data)
    } else res.status(400).send({ message: "no post found" })

}
matteo_dm
  • 61
  • 1
  • 3