Question

With a compound index like the following

db.data.ensureIndex({ userId: 1, myObject: 1 })

Will the following find use this index?

db.data.find({ 
  userId: 1,
  myObject: {
    a:'test',
    b:'test2'
  }
})

I know in Javascript that objects don't preserve their order so is this the same in Mongo?

So what will happen if I have documents with objects in different orders like this.

{
  _id: ObjectId,
  userId:1,
  myObject: {
    b: 'test',
    a: 'test2'
  }
},

{
  _id: ObjectId,
  userId:1,
  myObject: {
    b: 'test',
    a: 'test2'
  }
},

{
  _id: ObjectId,
  userId:2,
  myObject: {
    b: 'test',
    a: 'test2'
  }
}

Does the order of the properties matter when indexing an object like above?

EDIT: In the documentation, http://docs.mongodb.org/manual/core/index-single/ it says "When performing equality matches on subdocuments, field order matters and the subdocuments must match exactly."

And in their example, the following would work

db.factories.find( { metro: { city: "New York", state: "NY" } } )

but if the metro fields were the other way around it wont work

db.factories.find( { metro: { state: "NY", city: "New York" } } )

So how do you preserve the property order in Javascript/Node when the language itself doesn't support it?

Was it helpful?

Solution

Actually, JavasScript or JSON notation objects do preserve their order. While some top level properties might shuffle around if MongoDB has to move them as a document grows, generally speaking this "sub-level" document should not change from the order in which it was originally inserted.

That said some languages try to order their "Hash", "Map", "Dict" keys by default, and therefore it becomes important to find and "ordered" or "indexed" form when dealing with these, but that is another issue.

To your question of an "index" for MongoDB affecting this order, no it does not. In fact the index you have added, though it does not error as such, does not really have any value as an Object or {} essentially does not have a value for an index to act on.

What you can do is this:

db.data.ensureIndex({ "userId": 1, "myObject.a": 1 })

Which keeps an ascending index on the "a" property of your object. That is useful if this is regularly viewed in queries.

You can also have problems with positions if you attempt to query like this:

db.data.find({ "Object": { a: "test2", b: "test" } })

Where the actual stored keys are not in order. But this is typically fixed by the "dot notation" form:

db.data.find({ "Object.a": "test2", "Object.b": "test" })

Which will not care about the actual order of keys.

But the index you defined does not keep the "keys" in insertion order, that is entirely language specific

OTHER TIPS

The order matters for indexes on sub-documents. To quote the documentation:

This query returns the above document. When performing equality matches on subdocuments, field order matters and the subdocuments must match exactly. For example, the following query does not match the above document

Consider this document:

{
  _id: ObjectId(...),
  metro: {
           city: "New York",
           state: "NY"
         },
  name: "Giant Factory"
}

and this index:

db.factories.ensureIndex( { metro: 1 } )

this query matches:

db.factories.find( { metro: { city: "New York", state: "NY" } } )

and this one does not:

db.factories.find( { metro: { state: "NY", city: "New York" } } )

See http://docs.mongodb.org/manual/core/index-single/#indexes-on-subdocuments and http://docs.mongodb.org/manual/reference/method/db.collection.find/#query-subdocuments

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top