Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

find by _id with Mongoose

Tags:

I am having trouble with a simple findById with mongoose.

Confirmed the item exists in the DB

db.getCollection('stories').find({_id:'572f16439c0d3ffe0bc084a4'}) 

With mongoose

  Story.findById(topic.storyId, function(err, res) {     logger.info("res", res);     assert.isNotNull(res);   }); 

won't find it.

I also tried converting to a mongoId, still cannot be found (even though mongoose supposedly does this for you)

var mid = mongoose.Types.ObjectId(storyId); let story = await Story.findOne({_id: mid}).exec(); 

I'm actually trying to use this with typescript, hence the await.

I also tried the Story.findById(id) method, still cannot be found.

Is there some gotcha to just finding items by a plain _id field? does the _id have to be in the Schema? (docs say no)

I can find by other values in the Schema, just _id can't be used...


update: I wrote a short test for this.

describe("StoryConvert", function() {     it("should read a list of topics", async function test() {     let topics = await Topic.find({});      for (let i = 0; i < topics.length; i ++) {       let topic = topics[i];     // topics.forEach( async function(topic) {       let storyId = topic.storyId;       let mid = mongoose.Types.ObjectId(storyId);       let story = await Story.findOne({_id: mid});       // let story = await Story.findById(topic.storyId).exec();       // assert.equal(topic.storyId, story._id);       logger.info("storyId", storyId);       logger.info("mid", mid);       logger.info("story", story);       Story.findOne({_id: storyId}, function(err, res) {         if (err) {           logger.error(err);         } else {           logger.info("no error");         }         logger.info("res1", res);       });        Story.findOne({_id: mid}, function(err, res) {         logger.info("res2", res);       });        Story.findById(mid, function(err, res) {         logger.info("res3", res);         // assert.isNotNull(res);       });      }    });   }); 

It will return stuff like

Testing storyId 572f16439c0d3ffe0bc084a4  Testing mid 572f16439c0d3ffe0bc084a4  Testing story null  Testing no error  Testing res1 null  Testing res2 null  Testing res3 null 

I noticed that topic.storyId is a string not sure if that would cause any issues mapping to the other table. I tried also adding some type defs

  storyId: {     type: mongoose.Schema.Types.ObjectId,     required: false   } 

enter image description here

like image 863
dcsan Avatar asked May 20 '16 13:05

dcsan


People also ask

What does find by id return Mongoose?

Mongoose | findById() Function The findById() function is used to find a single document by its _id field. The _id field is cast based on the Schema before sending the command.

How do you use Find ID?

MongoDB provides a function with the name findById() which is used to retrieve the document matching the 'id' as specified by the user. In order to use findById in MongoDB, find() function is used. If no document is found matching the specified 'id', it returns null.

What does findById return in MongoDB?

findById returns the document where the _id field matches the specified id .

How do you use Mongoose findOne?

Mongoose | findOne() FunctionThe findOne() function is used to find one document according to the condition. If multiple documents match the condition, then it returns the first document satisfying the condition. Installation of mongoose module: You can visit the link to Install mongoose module.


2 Answers

Because this query finds the doc in the shell:

db.getCollection('stories').find({_id:'572f16439c0d3ffe0bc084a4'}) 

That means that the type of _id in the document is actually a string, not an ObjectId like Mongoose is expecting.

To find that doc using Mongoose, you'd have to define _id in the schema for Story as:

_id: { type: String } 
like image 98
JohnnyHK Avatar answered Sep 18 '22 00:09

JohnnyHK


If your Mongo schema is configured to use Object Id, you query in nodeJS using

models.Foo.findById(id)

where Foo is your model and id is your id. here's a working example

router.get('/:id', function(req, res, next) {     var id = req.params.id     models.Foo.findById(id)                 .lean().exec(function (err, results) {         if (err) return console.error(err)         try {             console.log(results)                     } catch (error) {             console.log("errror getting results")             console.log(error)         }      }) }) 

In Mongo DB your query would be

{_id:ObjectId('5c09fb04ff03a672a26fb23a')} 
like image 27
Lawrence Edmondson Avatar answered Sep 20 '22 00:09

Lawrence Edmondson