使用 Mongoose 通过 _id 查找

Posted

技术标签:

【中文标题】使用 Mongoose 通过 _id 查找【英文标题】:find by _id with Mongoose 【发布时间】:2016-09-17 18:49:58 【问题描述】:

我在使用 mongoose 的简单 findById 时遇到问题。

确认该项目存在于数据库中

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

与猫鼬

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

找不到。

我也尝试转换为 mongoId,但仍然找不到(即使据说 mongoose 会为你这样做)

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

我实际上是在尝试将它与打字稿一起使用,因此等待。

我也试过Story.findById(id)的方法,还是找不到。

仅通过简单的 _id 字段查找项目是否有一些问题? _id 必须在模式中吗? (文档说不)

我可以通过Schema中的其他值找到,只是_id不能用...


更新:我为此写了一个简短的测试。

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);
      );

    

  );


);

它会返回类似的东西

Testing storyId 572f16439c0d3ffe0bc084a4

Testing mid 572f16439c0d3ffe0bc084a4

Testing story null

Testing no error

Testing res1 null

Testing res2 null

Testing res3 null

我注意到topic.storyId 是一个字符串 不确定这是否会导致映射到另一个表的任何问题。 我也尝试添加一些类型定义

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

【问题讨论】:

_id 是默认创建的 不需要添加到模式中 你能检索记录吗?如果是这样,则在使用该_id 时尝试将其转换为toObject()。我不确定试一试!!! 【参考方案1】:

因为这个查询在 shell 中找到了文档:

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

这意味着文档中_id的类型实际上是一个字符串,而不是像Mongoose期望的ObjectId

要使用 Mongoose 查找该文档,您必须在 Story 的架构中将 _id 定义为:

_id:  type: String 

【讨论】:

这听起来很合适。我正在迁移一些在我们开始使用 mongo 之前创建的数据,因此类型可能不一致。我试试这个,谢谢! 这是问题所在,并且很好地发现了基本的 shell 查询(不使用 ObjectId)正在工作,所以这是放弃。 也适用于猫鼬,const modelSchema = new Schema( _id: type: String , strict: false );【参考方案2】:

如果您的 Mongo 架构配置为使用 Object Id,则您在 nodeJS 中使用查询

models.Foo.findById(id)

Foo 是你的模型,id 是你的 id。 这是一个工作示例

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)
         
    )
)

在 Mongo DB 中,您的查询将是

_id:ObjectId('5c09fb04ff03a672a26fb23a')

【讨论】:

【参考方案3】:

一种解决方案是使用 mongoose.ObjectId()

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

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

它可以工作,但很奇怪,因为我们使用的是 id 而不是 _id

【讨论】:

是的,简单易行!【参考方案4】:

我也遇到过这种情况。我就是这样解决的;

根据mongoose documentation,你需要告诉猫鼬 通过传递 lean 选项并将其设置为 true,返回原始 js 对象,而不是猫鼬文档。例如
Adventure.findById(id, 'name',  lean: true , function (err, doc) );

在你的情况下,它会是

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

【讨论】:

有点过时,但AdventureStory 听起来很有趣。你在做冒险游戏引擎吗?【参考方案5】:

如果 _id 是默认的 mongodb 键,则在您的模型中将 _id 的类型设置为:

_id: mongoose.SchemaTypes.ObjectId

然后使用mongoose就可以正常使用find了:

YourModel.find("_id": "5f9a86b77676e180c3089c3d");

【讨论】:

【参考方案6】:
models.findById(id)

试试这个。 参考链接:https://www.geeksforgeeks.org/mongoose-findbyid-function/

【讨论】:

【参考方案7】:

试试这个

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

 );

【讨论】:

任何错误或使用 id 正确的 id 存在于您的数据库中

以上是关于使用 Mongoose 通过 _id 查找的主要内容,如果未能解决你的问题,请参考以下文章

通过 _id 进行简单查询,mongoose 和 node.js 不起作用

如何在不使用 _id 字段但使用多个属性的情况下在 mongoose 中查找子文档

Mongoose 聚合查找 - 如何按特定 id 过滤

使用 MongoDB/Mongoose 按 ID 查找提交

Mongoose如何过滤填充字段

mongodb/mongoose findMany - 查找 ID 列在数组中的所有文档