Search code examples
mongodbmongodb-schema

MongoDB schema validation for unknown number of attributes?


I want to save documents like this:

_id: ObjectId('63fdf80e4ab6021dad4ed24b')
data: {
 index: 1,
 time: 1000,
 dataFieldOne: 1.44
 dataFieldTwo: 2.752
 ...
 dataFieldN: 0.15
}

There can be any number of dataFieldN attributes, but I want to make sure that data object has at least one. For example, this would be an invalid document:

_id: ObjectId('63fdf80e4ab6021dad4ed24b')
data: {
 index: 1,
 time: 1000
}

Can I validate for this with MongoDB schema validation rules? If there is a solution, how efficient would it be?


Solution

  • Something like this?

    db.createCollection(
    "collection",
    {
    validator: {
      $jsonSchema: {
        bsonType: 'object',
        properties: {
          data: {
            bsonType: 'object',
            additionalProperties: false,
            required: [
              'dataFieldOne'
            ],
            properties: {
              index: {
                bsonType: 'double'
              },
              time: {
                bsonType: 'double'
              },
              dataFieldOne: {
                bsonType: 'double'
              }
            },
            patternProperties: {
              '^dataField.+$': {
                bsonType: 'double'
              }
            }
          }
        }
      }
    }
    });
    

    Allows,

    [
        {
            "data": {
                "index": 1,
                "time": 1,
                "dataFieldOne": 1
            }
        },
        {
            "data": {
                "index": 1,
                "time": 1,
                "dataFieldOne": 1,
                "dataFieldTwo": 1
            }
        }
    ]
    

    Doesn't Allow

    [
        {
            "data": {
                "index": 1,
                "time": 1
            }
        },
        {
            "data": {
                "index": 1,
                "time": 1,
                "ns": 1
            }
        },
        {
            "data": {
                "index": 1,
                "time": 1,
                "dataFieldTwo": 1
            }
        },
        {
            "data": {
                "index": 1,
                "time": 1,
                "dataFieldOne": 1,
                "ns": 1
            }
        }
    ]