0

I'm having an issue with how arrays are inserted inside another array in my mongoose model. My model works fine and I'm able to update my db. First array is locationcategories[] which inside of that array, I have another categoryitems[] array. When I update the db, the categoryitems[] is stored at the beginning of the object but I needed to be stored at the end of the object.

I have this schema-model:

  var Schema = mongoose.Schema;

var locationSchema = new Schema({
    locationname: String,
    locationdescription: String,       
    locationcategories: [{ categoryorder: Number, categoryname: String,        
    categoryitems: [] }]       
});    
var Location = mongoose.model('Location', locationSchema);
export default Location;

Please notice the position of categoryitems : [] at the end of my category

Here is my code to create a category object:

Location.findByIdAndUpdate(
        { _id: data.location_id },
        {
            $push: {
                locationcategories: {
                    
                    categoryorder: data.category_order,
                    categoryname: data.category_name,
                    categorydescription: data.category_description,
                    categoryitems: []
                }
            }
        },

Please notice the position of categoryitems : [] at the end of my category

I get this in my mongodshell:

           {
                    "categoryitems" : [ ],
                    "_id" : ObjectId("5f7d0d072b42a22490621a76"),
                    "categoryorder" : 4,
                    "categoryname" : "cat87",
                    "categorydescription" : "location of categoryitems"
            }

Please observe where the categoryitems []. It's at the beginning of the object not at the end

That is the issue. It's suppose to insert the array at the end of the category object but instead, it is on top before the categoryorder. Is there a reason for that? I can live with it at the beginning but I'm just curious about the behavior. Am I doing something wrong? Or that is how the mongoose model works? Or is it a mongodb insert issue?

I'm very curious to figure it out. I appreciate any help.

Marco
  • 701
  • 9
  • 27

1 Answers1

1

The MongoDB server preserves key order in documents. This is because documents are stored as lists of key-value pairs (see here for details). Meaning, if you are inserting a complete document, whatever your driver has sent to the server is exactly the document you should receive when you query it back.

If you perform operations on the individual fields, the fields may get reordered. You'd have to consult individual operator documentation for any guarantees on key order; I don't recall seeing such guarantees in published documentation.

When you perform operations on multiple fields, it is likely that the order of fields will be preserved by virtue of the server applying the changes in the order you specify them. Again, as far as I know this is not guaranteed.

When you construct documents and send them to the server, and when you retrieve documents from the server and render them, there is a separate issue of the client preserving the key order. The behavior of programming languages in this respect varies. For example, Ruby has preserved key order for a long time, Python has started doing so relatively recently, and Elixir currently does not (and has not to my knowledge).

The issue of javascript preserving key order is covered in Does JavaScript guarantee object property order?. The behavior appears to be that:

  • ES2015 preserves key (property) order,
  • Previous versions of JS do not.

Then, the question is which language your application is using when it is inserting data and which language mongo shell is using when it is retrieving data.

To my knowledge mongo shell is not ES2015 compliant, therefore the most likely reason for you seeing a different order of keys in the shell is that the shell reordered them. If you query the data using the Node driver in an ES2015 environment I'd expect you to see the key order preserved.

D. SM
  • 10,060
  • 3
  • 9
  • 19
  • Thanks D. Glad that my schema-model were not the problem :) Interesting topic. I will query the data using my Node driver and see how it will return the object. – Marco Oct 07 '20 at 16:05