Update
Perhaps I misunderstood your initial question, but now it seems that the nature of your question has changed, so the information below is not relevant, but I leave it. :)
I checked your code and it works great for me. Mongoose does not execute any special code when you set properties that are not part of the schema (or several other special properties). JavaScript currently does not support calling code for properties that do not yet exist (therefore, Mongoose cannot interfere, for example, with a set of goo properties).
So, when you set the property:
foo.goo = { c: 1 };
Mongoose is not involved. If your console.log was something different from the code you displayed, I could see that it might report incorrectly.
Also, when you send return the results as JSON, JSON.stringify is JSON.stringify , which calls toString for your Mongoose model. When this happens, Mongoose uses only the properties defined in the schema. Thus, no additional properties are sent back by default. You changed the nature of the data array to directly point to Mongoose data, so it avoids this problem.
Normal behavior details
When you set the goo property using Mongoose, quite a few things happen. Mongoose creates tools for getting / setting properties using Object.defineProperty (some documents ). So, when you set the goo property that you defined as [String] , several things happen:
- Mongoose code is called before setting the value to an instance of the object (as opposed to a simple JavaScript object)
- Mongoose creates an array (optional) to store data (
MongooseArray ) that will contain the data in the array. In the example you provided, since you did not pass the array, it will be created. - Mongoose will try to cast your data to the desired type
- It will call
toString for the data passed as part of the cast.
Thus, as a result, the document now contains an array with a toString version of the object you submitted.
If you checked the contents of the goo property, you will see that now it is an array with one element, which is a string containing [object Object] . If you select a more basic type or match the storage type of the target property, you would see that a basic equality check would work.
Wiredprairie
source share