Uploaded image for project: 'Core Server'
  1. Core Server
  2. SERVER-5691

Queries with nested collections fail after MongoDB reorders fields post-update

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Critical - P2 Critical - P2
    • None
    • Affects Version/s: 2.0.4
    • Component/s: Querying
    • Labels:
      None
    • Environment:
    • ALL

      We are developing a straightforward Scala web application with a MongoDB backend using Salat+Casbah. We've noticed that sometimes our updates via Salat+Casbah fail to succeed. I can now explain why it's happening:

      1. We create documents using Salat which closely correspond to our model (Scala case classes). I can observe that the field ordering of the newly-inserted documents match the model.
      2. After some update, the fields in the document are updated to be in alphanumeric order (as documented).
      3. Salat is still able to deserialize the document as a proper object despite the field re-ordering.
      4. When we try to update the document using code like collection.update(old, new) as a form of optimistic locking – to ensure that the document hasn't been updated under us – this will fail even though the application's representation and the database's representation are isomorphic.

      Although we ran into this issue using Salat+Casbah, I was able to reproduce it using the Mongo CLI:

      # Insert a document with fields in alphanumeric order:
      var o = {
          "_id" : NumberLong(12000009),
          "createdBy" : NumberLong(1185),
          "creationDate" : ISODate("2008-02-06T06:00:00Z"),
          "draftHamsVendor" : {
              "id" : NumberLong(120),
              "name" : "Johnny Appleseed",
          },
          "name" : "Johnny Appleseed",
          "users" : [
              NumberLong(1185)
          ]
      }
      
      db.test.save(o)
      
      # Try to find the document using the model's field ordering:
      var p = {
          "_id" : NumberLong(12000009),
          "creationDate" : ISODate("2008-02-06T06:00:00Z"),
          "createdBy" : NumberLong(1185),
          "name" : "Johnny Appleseed",
          "draftHamsVendor" : {
              "name" : "Johnny Appleseed",
              "id" : NumberLong(120),
          },
          "users" : [
              NumberLong(1185)
          ]
      }
      
      > db.test.findOne(p)
      null
      

      For some reason, this issue only surfaces with nested documents, despite claims that key order is significant in queries. For example, the above inserted object will be found by both of the following queries:

      db.test.find({"creationDate" : ISODate("2008-02-06T06:00:00Z"), "createdBy" : NumberLong(1185)})
      db.test.find({"createdBy" : NumberLong(1185), "creationDate" : ISODate("2008-02-06T06:00:00Z")}) 
      

      I gather that both the significance of key ordering and the potential field re-ordering of documents are both by design, but the interaction between these two aspects seems to be a bad bug; the application runs fine until MongoDB needs to re-order fields in some documents. This is a subtle and unexpected bug, in part because the significance of key ordering in queries and documents is hardly documented at all.

            Assignee:
            Unassigned Unassigned
            Reporter:
            arun Arun Bhalla
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated:
              Resolved: