【问题标题】:Mongoose findOneAndUpdate cast error with custom _id自定义 _id 的 Mongoose findOneAndUpdate 转换错误
【发布时间】:2019-04-15 04:52:23
【问题描述】:

我有这样的 Person 架构:

const schema = new mongoose.Schema({
    _id: Number,
    name: String,
    birthday: Date,
    sex: String
});

schema.pre('findOneAndUpdate', async function (next) {
    try {
        let counter = await Counters.findByIdAndUpdate('person',
            {
                $inc: {
                    value: 1
                }
            },
            { new: true}
        );

        this._update._id = counter.value;

        next();
    }
    catch (err) {
        next(err);
    }
});

问题是当我尝试使用findOneAndUpdateupsert: true 添加一些新人时,它会生成一个CastError: Cast to ObjectId failed for value "18" at path "person"

我的_id 被定义为Number,所以我不明白它为什么要尝试将其转换为ObjectId

更新:

我发现了我的问题,Person 模型在其他模型中被引用,但我忘记更改其他模型中的 ref 类型...

person: {
    type: Number, //HERE
    ref: 'person',
    required: true
}

【问题讨论】:

  • 如果你能提供完整的代码就好了。我认为错误是来自另一个地方的东西,这里没有发布。您可以在这里发布您的upsert 代码吗?
  • @HardikShah 确实我找到了问题,我会更新我的问题,谢谢

标签: node.js mongodb mongoose mongoose-schema


【解决方案1】:

_id 是 MongoDB 的自动生成属性。如果您想为 Id 属性添加一个不同的名称,例如“personId”,或者您可以使用 MongoDB 自动生成的 Id 而无需创建单独的 Id。

【讨论】:

  • 可以使用 Mongoose 更改 _id 字段的类型,这就是我想要做的。问题是关于转换错误,因为我将我的 _id 字段声明为 Number 而不是 ObjectId
【解决方案2】:

您可以更改_id 属性的类型,虽然这不是一个好方法,但实际上您无法更改该值,因为它是不可变并代表primary 的键文档。请记住,_id 对于 MongoDB 生命周期非常重要,例如索引。如果您打算更改 Entity 键,则可以创建其他属性,例如 person_id

【讨论】:

  • 我一直在网上搜索很多关于如何使用 mongo 构建自定义 id 的教程/指南,这是很多人使用的一种方法 - 基本上是在 .pre('save') (或在这种情况下findOneAndUpdate) - 我也不想更改_id,如果它尚未设置,我想设置它以防upsert
  • 我明白了。可能教程用于生成其他文档(如副本),因为您将无法更新_id 本身,MongoDB 永远不会让您这样做。认为您可以根据需要创建多少文档,但每个文档都应该有一个唯一的 _id - 这是一种普通的方法,因为当集合包含超过 100 万个文档时,MongoDB 索引会更好地工作。
  • 创建文档时如果不给_id赋值,空值就是一个值,所以我认为你不能更新它,但老实说我我对此不是 100% 确定的,我会在这里做一些 PoC..
  • 我已经更新了我的问题并找到了问题,感谢您的贡献!
猜你喜欢
  • 1970-01-01
  • 2018-02-19
  • 2023-04-08
  • 1970-01-01
  • 2016-12-21
  • 2017-09-10
  • 2021-12-19
  • 2019-07-12
  • 2012-08-26
相关资源
最近更新 更多