MongoError:文档验证失败 - 如何将 float 和 int 插入同一字段 - 标记为 double?

AIo*_*Ion 3 validation jsonschema mongodb database-schema

我在插入 mongoDB 时遇到问题,因为好的对象不会通过 mongoDB validator

更糟糕的是,该错误是一个通用错误:Document failed validation在大型多嵌套对象中,该错误可能会使验证失败的具体位置变得混乱。

myValidatorIs =
  { validator:
      { $jsonSchema :
          { bsonType: "object"
          , required: [ "price" ]
          , properties:
              { price:
                  { bsonType: "double" // price needs to be a double, tried with decimal also.
                  , description: "must be a double/float and is required"
                  }
              }
          }
      }
  , validationAction: "error"
  , validationLevel: "strict"
  };

db.collection("collection").insertOne({ price : 4.5 }); // this works 
db.collection("collection").insertOne({ price : 4.0 }); // this doesn't - see error below
Run Code Online (Sandbox Code Playgroud)

错误:UnhandledPromiseRejectionWarning:MongoError:文档验证失败

我的应用程序需要不同的东西,但我在这里使用price.

现在,经过大量的试验和错误,我弄清楚了实际发生的情况。没有上面那么清楚。

基本上在 javascript 中,4.0( float) 隐式转换为4( integer) 并且这integer导致验证失败,因为不是float. 这是超级有线的。由于这些数据来自外部,我无法控制是否是floatinteger。JavaScript 只知道number.

这确实是问题所在吗?我的意思是我尝试了很多不同的事情,除了这种隐式类型转换之外,我看不到任何其他原因

因为在验证器中 - 如果我设置bsonType : "int"并给出它{price: 1},或者{price: 4.0}然后插入工作没有错误。

如何处理此类问题?如何插入{price: 4.0}

另外,我应该包括哪些设置才能使description我设置的字段出现在错误消息中?properties.price.description毕竟,如果不是为了创建更好的错误消息,那么目的是什么?

AIo*_*Ion 5

找到2个解决方案:

1. 一种有点有线的方法- 因为我最终mixed types在我的专栏中得到了。一般来说,您可能不想要混合类型,因为会增加复杂性 - 在我的情况下没有充分的理由将它们视为混合类型。

基本上,您可以使用类型列表来代替单一类型,如下所示:

bsonType: "double"bsonType: [ "double", "int" ]

此功能记录在此处:$types

myValidatorIs =
  { validator:
      { $jsonSchema :
          { bsonType: "object"
          , required: [ "price" ]
          , properties:
              { price:
                  { bsonType: [ "double", "int" ]  // add "int" in this array here
                  , description: "must be a double/float and is required"
                  }
              }
          }
      }
  , validationAction: "error"
  , validationLevel: "strict"
  };
Run Code Online (Sandbox Code Playgroud)

2.推荐的方法,在@lvrf的帮助下找到了这个

const MongoType_Double = require('mongodb').Double;

myValidatorIs =
  { validator:
      { $jsonSchema :
          { bsonType: "object"
          , required: [ "price" ]
          , properties:
              { price:
                  { bsonType: "double"  // leave this as double
                  , description: "must be a double/float and is required"
                  }
              }
          }
      }
  , validationAction: "error"
  , validationLevel: "strict"
  };

// then use the MongoType_Double constructor like so: 

db.collection("collection").insertOne({ price : MongoType_Double(4.0) }); // no errors..

Run Code Online (Sandbox Code Playgroud)

这也应该适用于所有其他类型,timestamp例如:

在此输入图像描述