使用Mongoose按_id查找

31

我在使用mongoose的findById方法时遇到了问题。

已确认数据库中存在该项。

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

使用Mongoose

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

实际上我正在尝试使用TypeScript,因此需要加上await关键字。

我还尝试了Story.findById(id)方法,但仍然找不到。

有没有什么技巧可以通过简单的_id字段找到项目? 是否必须在Schema中包含_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是一个字符串,不确定将其映射到其他表是否会导致任何问题。我还尝试添加了一些类型定义。

我注意到topic.storyId是一个字符串,不确定将其映射到其他表是否会导致任何问题。我还尝试添加了一些类型定义。

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

输入图像描述


_id默认已创建,无需在模式中添加。 您能够检索记录吗?如果可以,尝试将其转换为toObject()使用_id。 我不确定,试试看吧! - Shantanu Madane
9个回答

22

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

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

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

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

_id: { type: String }

这听起来像是正确的情况。我正在迁移一些在我们开始使用Mongo之前创建的数据,因此类型可能不一致。我会尝试这个方法,谢谢! - dcsan
这是问题所在,而且很好地发现了基本的shell查询(不使用ObjectId)是工作的,所以那就是线索。 - dcsan
也适用于mongoose,const modelSchema = new Schema({ _id: { type: String } }, { strict: false }); - robert.batty

8
如果您的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)
        } 
    })
})

在MongoDB中,您的查询应该是:
{_id:ObjectId('5c09fb04ff03a672a26fb23a')}

3

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

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

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

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


是的,简单易懂! - SowingFiber

1

这是我们现在的做法:

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

1
如果_id是默认的mongodb键,那么在你的模型中将_id的类型设置为这个:
_id: mongoose.SchemaTypes.ObjectId

然后使用mongoose,您可以使用普通的查找:

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

0

我也遇到了这种情况。这是我解决它的方法:

  • 根据mongoose文档,你需要通过传递lean选项并将其设置为true来告诉mongoose返回原始js对象而不是mongoose文档。例如:
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);
});

有点离题,但“Adventure”和“Story”听起来很有趣。你在制作冒险游戏引擎吗? - dcsan

0
用于与模式和默认的mongo键_id一起使用。在模式中设置_id的类型。
const mongoose = require('mongoose');
 
const projectSchema = new mongoose.Schema({
    _id: mongoose.SchemaTypes.ObjectId,
    //Add another field
});
 

const Project = mongoose.model('Project', projectSchema);
module.exports.ProjectsService = class ProjectsService {

    async getProjectById(req, res) {
        try {
            const projectId = req.params.projectId;             
            let project = await Project.find({ "_id": projectId })
            res.json(project);
        } catch (err) {
            throw err
        };
    };
};

-1

-2

试试这个

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

 });

请使用您数据库中存在的正确ID,以避免任何错误。 - Manoj Ojha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接