MongoError: Document failed validation - How to insert both float and int into the same field - which is marked as double?

江枫思渺然 提交于 2021-01-28 14:45:33

问题


I'm having problems with inserting into mongoDB because good objects don't pass the mongoDB validator.

To make it worse, the error is a generic: Document failed validation which in a big multi-nested object can make things confusing regarding where exactly this validation fails.

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

ERROR: UnhandledPromiseRejectionWarning: MongoError: Document failed validation

My app needs something different but i simplified it here by using price.

Now after lots of trial and error i figured out what actually happens. Was not as clear as above.

Basically in javascript the 4.0 (float) is implicitly transformed to 4 (integer) And this integer fails the validation since is not a float. Which is super wired. Since this data comes from outside, i can't control if is float or integer. Javascript only knows about number.

Is this indeed the problem? I mean i tried lots of different things and i can't see any other reason other then this implicit type conversion.

Because in the validator - if i set bsonType : "int" and i give it {price: 1} or {price: 4.0} then the insertion works with no errors.

How to deal with this type of issue? How to insert {price: 4.0}?

Also what settings should i include to make that description field i set to appear in the error message? After all what is the purpose of properties.price.description if not to create better error messages ?


回答1:


Found 2 solutions:

1. A somewhat wired approach - because i endup with mixed types in my column. In general, you might not want mixed types since adds complexity - and there is no good reason for them to be considered mixed in my case.

Basically instead of a single type, you can use a list of types like so:

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

This feature is documented here: $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"
  };

2. The recommended approach, found this with help from @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..

This should also work for all the other types like timestamp and such:



来源:https://stackoverflow.com/questions/57810998/mongoerror-document-failed-validation-how-to-insert-both-float-and-int-into-t

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!