简体   繁体   English

使用 Mongoose 通过 _id 查找

[英]find by _id with Mongoose

I am having trouble with a simple findById with mongoose.我在使用猫鼬的简单 findById 时遇到了麻烦。

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)我还尝试转换为 mongoId,但仍然找不到(即使据说 mongoose 会为您执行此操作)

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.我也试过Story.findById(id)方法,还是找不到。

Is there some gotcha to just finding items by a plain _id field?仅通过简单的_id字段查找项目是否有一些问题? does the _id have to be in the Schema? _id 必须在模式中吗? (docs say no) (文档说不)

I can find by other values in the Schema, just _id can't be used...我可以通过 Schema 中的其他值找到,只是_id不能使用...


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.我注意到topic.storyId是一个字符串,不确定这是否会导致映射到另一个表的任何问题。 I tried also adding some type defs我也尝试添加一些类型定义

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

在此处输入图像描述

Because this query finds the doc in the shell:因为这个查询在 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.这意味着文档中_id的类型实际上是一个字符串,而不是像 Mongoose 所期望的ObjectId

To find that doc using Mongoose, you'd have to define _id in the schema for Story as:要使用 Mongoose 查找该文档,您必须在Story的架构中将_id定义为:

_id: { type: String }

If your Mongo schema is configured to use Object Id, you query in nodeJS using如果您的 Mongo 模式配置为使用 Object Id,则在 nodeJS 中使用

models.Foo.findById(id)

where Foo is your model and id is your id.其中Foo是您的模型, id是您的 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在 Mongo DB 中,您的查询将是

{_id:ObjectId('5c09fb04ff03a672a26fb23a')}

One solution is to use mongoose.ObjectId()一种解决方案是使用 mongoose.ObjectId()

const Model = require('./model')
const mongoose = require('mongoose')

Model.find({ id: mongoose.ObjectId(userID) })

It works, but it is weird because we are using id instead of _id它有效,但很奇怪,因为我们使用的是 id 而不是 _id

I got into this scenario too.我也陷入了这种情况。 This was how I solved it;这就是我解决它的方法;

  • According to the mongoose documentation , you need to tell mongoose to return the raw js objects, not mongoose documents by passing the lean option and setting it to true.根据mongoose 文档,您需要通过传递lean选项并将其设置为 true 来告诉 mongoose 返回原始 js 对象,而不是 mongoose 文档。 eg例如
Adventure.findById(id, 'name', { lean: true }, function (err, doc) {});

in your situation, it would be在你的情况下,它会是

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

If _id is the default mongodb key, in your model set the type of _id as this:如果 _id 是默认的 mongodb 键,则在您的模型中将 _id 的类型设置为:

_id: mongoose.SchemaTypes.ObjectId

Then usind mongoose you can use a normal find:然后使用 mongoose 你可以使用正常的查找:

YourModel.find({"_id": "5f9a86b77676e180c3089c3d"});
models.findById(id)

TRY THIS ONE .试试这个。 REF LINK : https://www.geeksforgeeks.org/mongoose-findbyid-function/参考链接: https ://www.geeksforgeeks.org/mongoose-findbyid-function/

This is how we do it now:这就是我们现在的做法:

const { mongoose } = require("mongoose");
YourModel.find({ _id: mongoose.Types.ObjectId("572f16439c0d3ffe0bc084a4") });

Try this尝试这个

 Story.findOne({_id:"572b19509dac77951ab91a0b"}, function(err, story){
                if (err){
                    console.log("errr",err);
                    //return done(err, null);
                }else{
                    console.log(story);
                }

 });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM