diff --git a/db/matcher.cpp b/db/matcher.cpp index 4a4175e62a6..35fe56fe4a9 100644 --- a/db/matcher.cpp +++ b/db/matcher.cpp @@ -386,7 +386,6 @@ namespace mongo { compareOp - Equality, LT, GT, etc. deep - out param. set to true/false if we scanned an array isArr - - nextArr - true if an array has already been found Special forms: @@ -399,7 +398,8 @@ namespace mongo { 0 missing element 1 match */ - int JSMatcher::matchesDotted(const char *fieldName, const BSONElement& toMatch, const BSONObj& obj, int compareOp, bool *deep, bool isArr, bool nextArr) { + int JSMatcher::matchesDotted(const char *fieldName, const BSONElement& toMatch, const BSONObj& obj, int compareOp, bool *deep, bool isArr) { + if ( compareOp == BSONObj::NE ) return matchesNe( fieldName, toMatch, obj, deep ); if ( compareOp == BSONObj::NIN ) { @@ -413,10 +413,10 @@ namespace mongo { } BSONElement e; - if ( !constrainIndexKey_.isEmpty() ) { + bool indexed = !constrainIndexKey_.isEmpty(); + if ( indexed ) { e = obj.getFieldUsingIndexNames(fieldName, constrainIndexKey_); assert( !e.eoo() ); - nextArr = true; } else { if ( isArr ) { BSONObjIterator ai(obj); @@ -425,7 +425,7 @@ namespace mongo { BSONElement z = ai.next(); if ( z.type() == Object ) { BSONObj eo = z.embeddedObject(); - int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep, false, true); + int cmp = matchesDotted(fieldName, toMatch, eo, compareOp, deep, false); if ( cmp > 0 ) { if ( deep ) *deep = true; return 1; @@ -447,16 +447,16 @@ namespace mongo { return -1; BSONObj eo = se.embeddedObject(); - return matchesDotted(p+1, toMatch, eo, compareOp, deep, se.type() == Array, nextArr); + return matchesDotted(p+1, toMatch, eo, compareOp, deep, se.type() == Array); } else { e = obj.getField(fieldName); } } - if ( ( e.type() != Array || nextArr || compareOp == BSONObj::opALL || compareOp == BSONObj::opSIZE ) && + if ( ( e.type() != Array || indexed || compareOp == BSONObj::opALL || compareOp == BSONObj::opSIZE ) && valuesMatch(e, toMatch, compareOp, deep) ) { return 1; - } else if ( e.type() == Array && compareOp != BSONObj::opALL && compareOp != BSONObj::opSIZE && !nextArr ) { + } else if ( e.type() == Array && compareOp != BSONObj::opALL && compareOp != BSONObj::opSIZE ) { BSONObjIterator ai(e.embeddedObject()); while ( ai.more() ) { BSONElement z = ai.next(); diff --git a/db/matcher.h b/db/matcher.h index 4d09bb45668..d8500ee4db9 100644 --- a/db/matcher.h +++ b/db/matcher.h @@ -66,7 +66,7 @@ namespace mongo { int matchesDotted( const char *fieldName, const BSONElement& toMatch, const BSONObj& obj, - int compareOp, bool *deep, bool isArr = false, bool nextArr = false); + int compareOp, bool *deep, bool isArr = false); int matchesNe( const char *fieldName, diff --git a/dbtests/querytests.cpp b/dbtests/querytests.cpp index 1e13193bef9..a8d453a97fe 100644 --- a/dbtests/querytests.cpp +++ b/dbtests/querytests.cpp @@ -540,8 +540,8 @@ namespace QueryTests { private: void check( const string &hintField ) { const char *ns = "unittests.querytests.SubobjArr"; - ASSERT( !client().query( ns, Query( "{'a.b':1}" ).hint( BSON( hintField << 1 ) ) )->more() ); - ASSERT( client().query( ns, Query( "{'a.b':[1]}" ).hint( BSON( hintField << 1 ) ) )->more() ); + ASSERT( client().query( ns, Query( "{'a.b':1}" ).hint( BSON( hintField << 1 ) ) )->more() ); + ASSERT( !client().query( ns, Query( "{'a.b':[1]}" ).hint( BSON( hintField << 1 ) ) )->more() ); } }; diff --git a/jstests/nin.js b/jstests/nin.js index fc4bb6dcfbf..cb69bab3bdb 100644 --- a/jstests/nin.js +++ b/jstests/nin.js @@ -26,8 +26,8 @@ doTest = function() { assert.eq( 4, t.find( { a: { $nin: [ 2 ] } } ).count() ); t.save( { a: [ { b: [ 10, 11 ] }, 11 ] } ); - assert.eq( 1, t.find( { 'a.b': { $nin: [ 10 ] } } ).count() ); - assert.eq( 0, t.find( { 'a.b': { $nin: [ [ 10, 11 ] ] } } ).count() ); + assert.eq( 0, t.find( { 'a.b': { $nin: [ 10 ] } } ).count() ); + assert.eq( 1, t.find( { 'a.b': { $nin: [ [ 10, 11 ] ] } } ).count() ); assert.eq( 7, t.find( { a: { $nin: [ 11 ] } } ).count() ); t.save( { a: { b: [ 20, 30 ] } } );