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

Incosistent behavior with $or and $elemMatch

    • Type: Icon: Bug Bug
    • Resolution: Duplicate
    • Priority: Icon: Major - P3 Major - P3
    • None
    • Affects Version/s: 2.4.8, 2.6.3
    • Component/s: Querying, Write Ops
    • Labels:
      None
    • Environment:
      Mac OS X 10.7.5.
    • ALL
    • Hide

      If you do queries:

      > db.test.insert({nested: [{a: 1, slug: 'aaa'}, {a: 1, slug: 'aaa'}, {a: 2, slug: 'aaa'}]})
      > db.test.find()
      { "_id" : ObjectId("52763c5cb6786ce4ff406cbf"), "nested" : [ { "a" : 1, "slug" : "aaa" }, { "a" : 1, "slug" : "aaa" }, { "a" : 2, "slug" : "aaa" } ] }
      > db.test.update({'nested.a': 1, $or: [{'nested': {$elemMatch: {a: 1, slug: {$exists: true}}}}]}, {$unset: {'nested.$.slug': ''}})
      > db.test.find()
      { "_id" : ObjectId("52763c5cb6786ce4ff406cbf"), "nested" : [ { "a" : 1 }, { "a" : 1, "slug" : "aaa" }, { "a" : 2, "slug" : "aaa" } ] }
      > db.test.update({'nested.a': 1, $or: [{'nested': {$elemMatch: {a: 1, slug: {$exists: true}}}}]}, {$unset: {'nested.$.slug': ''}})
      > db.test.find()
      { "_id" : ObjectId("52763c5cb6786ce4ff406cbf"), "nested" : [ { "a" : 1 }, { "a" : 1, "slug" : "aaa" }, { "a" : 2, "slug" : "aaa" } ] }
      

      I would expect that the second update will remove slug from second a == 1 array element. But it does not. On the other hand, if I run:

      db.test.update({'nested.a': 1, 'nested': {$elemMatch: {a: 1, slug: {$exists: true}}}}, {$unset: {'nested.$.slug': ''}})
      

      Second slug is correctly removed.

      Show
      If you do queries: > db.test.insert({nested: [{a: 1, slug: 'aaa' }, {a: 1, slug: 'aaa' }, {a: 2, slug: 'aaa' }]}) > db.test.find() { "_id" : ObjectId( "52763c5cb6786ce4ff406cbf" ), "nested" : [ { "a" : 1, "slug" : "aaa" }, { "a" : 1, "slug" : "aaa" }, { "a" : 2, "slug" : "aaa" } ] } > db.test.update({ 'nested.a' : 1, $or: [{ 'nested' : {$elemMatch: {a: 1, slug: {$exists: true }}}}]}, {$unset: { 'nested.$.slug' : ''}}) > db.test.find() { "_id" : ObjectId( "52763c5cb6786ce4ff406cbf" ), "nested" : [ { "a" : 1 }, { "a" : 1, "slug" : "aaa" }, { "a" : 2, "slug" : "aaa" } ] } > db.test.update({ 'nested.a' : 1, $or: [{ 'nested' : {$elemMatch: {a: 1, slug: {$exists: true }}}}]}, {$unset: { 'nested.$.slug' : ''}}) > db.test.find() { "_id" : ObjectId( "52763c5cb6786ce4ff406cbf" ), "nested" : [ { "a" : 1 }, { "a" : 1, "slug" : "aaa" }, { "a" : 2, "slug" : "aaa" } ] } I would expect that the second update will remove slug from second a == 1 array element. But it does not. On the other hand, if I run: db.test.update({ 'nested.a' : 1, 'nested' : {$elemMatch: {a: 1, slug: {$exists: true }}}}, {$unset: { 'nested.$.slug' : ''}}) Second slug is correctly removed.

      There seems to be inconsistency when using $or in combination with $elemMatch. See steps to reproduce.

            Assignee:
            david.storch@mongodb.com David Storch
            Reporter:
            mitar NOVALUE Mitar
            Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

              Created:
              Updated:
              Resolved: