How does Mongoose/MongoDB handle properties with undefined value when creating or updating document?

Note: This post is a details-post for the post: Learning web app development through free online tutorials – Organized Notes and Log, https://raviswdev.blogspot.com/2024/03/learning-web-app-development-through.html .

This post is in the context of my recent post: Notes on creating Node Express & MongoDB (simple) Blog API and refactoring React tutorial Blog App to use it .

The schema used for the MongoDB collection used by the project code is as follows:

    const schema = new mongoose.Schema({
      title: {
        type: String,
        required: [true, "title has to be specified"],
        trim: true,
      },
      body: {
        type: String,
      },
      datetime: { type: Date, default: Date.now },
    });
  

A test case was if only title is provided in Postman post request. In some code that calls Mongoose {Model_Name}.create (Post.create) method, body and datetime are set as undefined if req.body does not have them. So Post.create is passed body and datetime properties with undefined as their values. Mongoose and MongoDB don't complain. A new document is created without body property and with datetime property (set to current datetime).

I wanted to read the documentation for this behaviour and tried to look up Mongoose documentation for create, https://mongoosejs.com/docs/api/model.html#Model.create() . But it did not provide details on how it handles undefined properties. Browsing the net did not give suitable results though I got this related page: Weird behaviour when saving documents with undefined properties which have default values in the model #3981, https://github.com/Automattic/mongoose/issues/3981 where the discussion seems to imply that Mongoose/MongoDB handles undefined values for properties as it handled my case (property dropped if there is no default value, property created if there is a default value, with the default value).

https://www.mongodb.com/docs/drivers/node/current/fundamentals/bson/undefined-values/ gives a good explanation of how MongoDB handles undefined values. It states, "In this guide, you can learn to control how the driver serializes undefined values. By default, the driver serializes undefined values as null values during write operations." It goes on to give further info.

My understanding of what it says is that by default (ignoreUndefined set as false), undefined properties are created (in the document) and assigned null value. So, in my case, if Mongoose does not change this ignoreUndefined, body should have been created with null.

Options section in https://mongoosejs.com/docs/connections.html pointed me to (eventually) https://mongodb.github.io/node-mongodb-native/4.2/interfaces/MongoClientOptions.html#ignoreUndefined which states:

Optional ignoreUndefined
ignoreUndefined?: boolean

Inherited from BSONSerializeOptions.ignoreUndefined
Defined in node_modules/bson/bson.d.ts:954

serialize will not emit undefined fields (default:true)
----

Hmm. So above page says ignoreUndefined is set as true by default which conflicts with earlier MongoDB page info. Both are MongoDb pages and not Mongoose pages! Hmm. Maybe I got something wrong. Or is this a MongoDB documentation issue which can be resolved only by looking at the code specified above?

I located the code in node_modules/bson/bson.d.ts at line number 1148, and have copy-pasted it below:

  /**
  * serialize will not emit undefined fields
  * note that the driver sets this to `false`
  * @defaultValue `true`
  */
 ignoreUndefined?: boolean;

Hmm. So yes, ignoreUndefined is set to true in the bson code!

From https://www.mongodb.com/docs/drivers/java/sync/current/fundamentals/data-formats/document-data-format-bson/ : "BSON, or Binary JSON, is the data format that MongoDB uses to organize and store data. This data format includes all JSON data structure types and adds support for types including dates, different size integers, ObjectIds, and binary data."

From https://www.couchbase.com/resources/concepts/json-vs-bson/ : "Binary vs. text: BSON is a binary-encoded format, whereas JSON is a text-based format. This means that BSON is compact for transmitting over a network, while JSON is human-readable and easier to work with in various contexts." ... "BSON is natively supported only by MongoDB. JSON, on the other hand, is widely supported and can be used with distributed database systems, programming languages, and platforms."

OK ... Understood why my code is behaving in this manner. But that took too much time to confirm! I think that's a downside with Open Source stuff - the documentation is not great and seems to be somewhat inaccurate at times, due to which one has to go to the code of the open source package one is using, to confirm.

Comments

Archive