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 }
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.
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.
findById returns the document where the _id field matches the specified id .
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.
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 }
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')}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With