How to generically avoid inserting the zero-id for MongoDB objects (using golang) etc

82 Views Asked by At

Not a big fan of Golang's zero values, and it will automatically generate zero-value ObjectIds like this:

I am currently using JSON Schema like so:

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://vibe.com/wss/src/common/mongo/mongo-message-ack",
  "$ref": "#/$defs/MongoMessageAck",
  "$defs": {
    "MongoMessageAck": {
      "properties": {
        "_id": {
          "$ref": "#/$defs/ObjectID"
        },
        "MessageId": {
          "$ref": "#/$defs/ObjectID"
        }
      },
      "additionalProperties": false,
      "type": "object",
      "required": [
        "_id",
        "MessageId",
      ]
    },
    "ObjectID": {
      "items": {
        "type": "integer"
      },
      "type": "array",
      "maxItems": 12,
      "minItems": 12
    }
  }
}

this part does some validation of ObjectIds:

   "ObjectID": {
      "items": {
        "type": "integer"
      },
      "type": "array",
      "maxItems": 12,
      "minItems": 12
    }

and I also saw this online:

  "$expr": {
    "$and": [
      { "$ne": ["$_id", ObjectId("000000000000000000000000")] },
      { "$ne": ["$MessageId", ObjectId("000000000000000000000000")] }
    ]
  }

however the $expr thing is not valid JSON, which isn't as convenient (although doable).

Is there a good way to prevent zero-ids from ending up in Mongo?

One solution is to create a unique index for each object id and then pre-insert zero-id's for all those fields, but I would like to find another layer on top of that to ensure this, in case I forget to create an index for a random object id field...

1

There are 1 best solutions below

1
Jeremy Fiel On

First off, ObjectID shouldn't be an array.

Besides that, the use of min/maxItems is a constraint for the number of items in the array [1,2,3], not the length of the array value [123]

Are you trying to limit the array to 12 items or the length of the value to 12 digits? Those are two different constraints. The latter is not fully supported by JSON Schema, although you can kind of accomplish it with a hacky solution if you don't mind handling parsing errors because JSON doesn't allow leading zeros.

stick tap to this answer explaining DecimalIntegerLiteral in JSON: https://stackoverflow.com/a/27361732/8564731

This would require the number to be at least 100_000_000_000 and no larger than 999_999_999_999

{
   "ObjectID": {
      "items": {
        "type": "integer",
        "exclusiveMinimum": 99999999999,
        "exclusiveMaximum": 1000000000000
      },
      "type": "array",
      "minItems": 1
    }
}

The other consideration should be if you are using the MongoDB ObjectID as intended. Are you inserting an integer because you're trying to create a unique value or you are trying to use the modified timestamp as explained in their docs? https://www.mongodb.com/docs/manual/reference/method/ObjectId/#specify-an-integer-string

If you want to use a string, you can accomplish the length constraints with below, assuming the array is not required per my previous comment

{
    "ObjectID": {
        "type": "string",
        "pattern": "[a-z0-9]+",
        "minLength": 12,
        "maxLength": 12
    }
}