使用 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);
);
【讨论】:
有点过时,但Adventure
和Story
听起来很有趣。你在做冒险游戏引擎吗?【参考方案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 不起作用