diff options
-rw-r--r-- | db/matcher.cpp | 27 | ||||
-rw-r--r-- | db/matcher.h | 1 | ||||
-rw-r--r-- | mongo.xcodeproj/project.pbxproj | 2 |
3 files changed, 30 insertions, 0 deletions
diff --git a/db/matcher.cpp b/db/matcher.cpp index baaeee52bfc..a6717c51dcd 100644 --- a/db/matcher.cpp +++ b/db/matcher.cpp @@ -299,6 +299,18 @@ namespace mongo { BSONObjIterator i(jsobj); while ( i.more() ) { BSONElement e = i.next(); + + const char *ef = e.fieldName(); + if ( ef[1] == 'o' && ef[2] == 'r' && ef[3] == 0 ) { + uassert( 13086, "$or must be a nonempty array", e.type() == Array && e.embeddedObject().nFields() > 0 ); + BSONObjIterator j( e.embeddedObject() ); + while( j.more() ) { + BSONElement f = j.next(); + uassert( 13087, "$or match element must be an object", f.type() == Object ); + _orMatchers.push_back( shared_ptr< Matcher >( new Matcher( f.embeddedObject(), constrainIndexKey ) ) ); + } + break; + } if ( ( e.type() == CodeWScope || e.type() == Code || e.type() == String ) && strcmp(e.fieldName(), "$where")==0 ) { // $where: function()... @@ -704,6 +716,21 @@ namespace mongo { /* assuming there is usually only one thing to match. if more this could be slow sometimes. */ + // for now $or must be the only top level field if present + if ( _orMatchers.size() > 0 ) { + for( vector< shared_ptr< Matcher > >::const_iterator i = _orMatchers.begin(); + i != _orMatchers.end(); ++i ) { + if( details ) { + // just to be safe - may not be strictly necessary. + details->reset(); + } + if ( (*i)->matches( jsobj, details ) ) { + return true; + } + } + return false; + } + // check normal non-regex cases: for ( unsigned i = 0; i < basics.size(); i++ ) { ElementMatcher& bm = basics[i]; diff --git a/db/matcher.h b/db/matcher.h index 6e2cad7233e..7eac2e97da7 100644 --- a/db/matcher.h +++ b/db/matcher.h @@ -181,6 +181,7 @@ namespace mongo { // so we delete the mem when we're done: vector< shared_ptr< BSONObjBuilder > > _builders; + vector< shared_ptr< Matcher > > _orMatchers; friend class CoveredIndexMatcher; }; diff --git a/mongo.xcodeproj/project.pbxproj b/mongo.xcodeproj/project.pbxproj index f0042da60be..05913868189 100644 --- a/mongo.xcodeproj/project.pbxproj +++ b/mongo.xcodeproj/project.pbxproj @@ -538,6 +538,7 @@ 93E5B88F10D7FF890044F9E4 /* v8_wrapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = v8_wrapper.h; sourceTree = "<group>"; }; 93E727090F4B5B5B004F9B5D /* shardkey.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shardkey.cpp; sourceTree = "<group>"; }; 93E7270A0F4B5B5B004F9B5D /* shardkey.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shardkey.h; sourceTree = "<group>"; }; + 93E8A4381173E6480025F7F8 /* or1.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = or1.js; sourceTree = "<group>"; }; 93F0957010E165E50053380C /* basic.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = basic.js; sourceTree = "<group>"; }; 93F095CC10E16FF70053380C /* shellfork.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = shellfork.js; sourceTree = "<group>"; }; C6859E8B029090EE04C91782 /* mongo.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = mongo.1; sourceTree = "<group>"; }; @@ -779,6 +780,7 @@ 934BEB9A10DFFA9600178102 /* jstests */ = { isa = PBXGroup; children = ( + 93E8A4381173E6480025F7F8 /* or1.js */, 930750A8114EFB9900272A70 /* update_addToSet.js */, 930750A9114EFB9900272A70 /* update_arraymatch1.js */, 930750AA114EFB9900272A70 /* update_arraymatch2.js */, |