【问题标题】:Handling mongoose population exceptions处理猫鼬种群异常
【发布时间】:2018-09-13 12:02:48
【问题描述】:

我们有一些 Mongoose (5.x) 模型,并且正在使用 ref 和 populate 来获取一些孩子。当填充失败时,我无法处理异常。

const postSchema = new mongoose.Schema({
    title: {
        type: String,
    },
    url : {
        type: String,
    },
    domain:{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'Domain'
    },
    user:{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'User'
    }
});

postSchema 模型的域属性最初是 String 类型,最近升级为 ObjectID Ref。现有数据现在混合在一起 - 大多数帖子都有一个字符串作为域,而少数帖子有一个 ObjectId。删除这些数据并重新开始会很简单,但我决心让代码优雅地处理这个问题并以正确的方式处理这个问题。

我们有一个(简化的)查询:

const posts = model.find().limit(20).populate('user').populate('domain');
posts.catch(err => console.log('Error getting posts ' + err);

运行此查询会引发一些预期错误和一些意外错误。这些错误会阻止端点返回任何数据。

获取帖子时出错 CastError: Cast to ObjectId failed for value 模型“域”[2] 的路径“_id”中的“www.google.com” (节点:5740)

UnhandledPromiseRejectionWarning:未处理的承诺拒绝 (rejection id: 1): CastError: Cast to ObjectId failed for value 模型“域”的路径“_id”中的“www.google.com”

为什么我收到 UnhandledPromseRejectionWarning,不是 .catch() 处理拒绝?

当遇到错误时,我想要两种可能的结果之一:

  • 将该文档的域设置为空
  • 如果不可能,请将该文档从结果集中排除并继续

这些选项中的任何一个都可能吗?

【问题讨论】:

    标签: node.js mongodb mongoose promise


    【解决方案1】:

    您可以尝试使用$type 运算符:

    const posts = model.find({ domain: { $type: 'objectId' } }).limit(20).populate('user').populate('domain');
    

    这样您可以从结果中排除所有带有“字符串”域的文档。

    顺便说一句,最好的解决方案是使数据同质化,也许使用一个循环,为所有字符串域找到正确的域文档并使用其 _id 作为参考。

    【讨论】:

      【解决方案2】:

      你可以试试custom schema types

      const mongoose = require('mongoose');
      const {ObjectId} = mongoose.Schema.Types;
      if (!('DomainId' in mongoose.Schema.Types)) {
        class DomainId extends mongoose.SchemaType {
          constructor (value, options) {
            value = (value instanceof ObjectId) ? value : new ObjectId(value);
            super(value, options, 'DomainId');
      
          }
          cast (val) {
            const _val = (value instanceof ObjectId) ? value : new ObjectId(value);
            return _val;
          }
        }
        mongoose.SchemaTypes.DomainId = DomainId;
      }
      

      【讨论】:

        猜你喜欢
        • 2016-07-31
        • 2015-10-17
        • 2019-09-13
        • 2017-06-02
        • 1970-01-01
        • 2018-02-10
        • 2013-11-27
        • 2016-12-17
        • 2016-07-02
        相关资源
        最近更新 更多