diff options
author | Aaron <aaron@10gen.com> | 2010-03-22 10:53:06 -0700 |
---|---|---|
committer | Aaron <aaron@10gen.com> | 2010-03-22 10:53:06 -0700 |
commit | 5d7f77dda7126caacd4823c180ba59cd28a435f8 (patch) | |
tree | c85b91f83e7594d38c9bea233b259b62b2219ab9 | |
parent | 82be9226a67a465e62615d088c90d6085f9e841d (diff) | |
parent | 254f59877e4402c510914a7ba7025dbdbe504e6d (diff) | |
download | mongo-5d7f77dda7126caacd4823c180ba59cd28a435f8.tar.gz |
Merge branch 'master' of github.com:mongodb/mongo
-rw-r--r-- | db/jsobj.cpp | 83 | ||||
-rw-r--r-- | db/jsobj.h | 2 | ||||
-rw-r--r-- | jstests/regex_embed1.js | 25 |
3 files changed, 74 insertions, 36 deletions
diff --git a/db/jsobj.cpp b/db/jsobj.cpp index fa3e93a231b..9f9a6840303 100644 --- a/db/jsobj.cpp +++ b/db/jsobj.cpp @@ -844,49 +844,62 @@ namespace mongo { return e; } - /* jul09 : 'deep' and this function will be going away in the future - kept only for backward compatibility of datafiles for now. */ - void trueDat( bool *deep ) { - if( deep ) - *deep = true; - } + void BSONObj::getFieldsDotted(const char *name, BSONElementSet &ret ) const { + BSONObjIterator i(*this); + while ( i.more() ){ + BSONElement e = i.next(); + FieldCompareResult cmp = compareDottedFieldNames( name , e.fieldName() ); + switch ( cmp ){ - void BSONObj::getFieldsDotted(const char *name, BSONElementSet &ret, bool *deep ) const { - BSONElement e = getField( name ); - if ( e.eoo() ) { - const char *p = strchr(name, '.'); - if ( p ) { - string left(name, p-name); - BSONElement e = getField( left ); - if ( e.type() == Array ) { - trueDat( deep ); - BSONObjIterator i( e.embeddedObject() ); - while( i.moreWithEOO() ) { - BSONElement f = i.next(); - if ( f.eoo() ) - break; + case LEFT_BEFORE: + case RIGHT_BEFORE: + break; + + case RIGHT_SUBFIELD: + assert(0); + break; + + case LEFT_SUBFIELD: { + const char * next = name + strlen( e.fieldName() ) + 1; + bool allDigits = false; + if ( isdigit( *next ) ){ + const char * temp = next + 1; + while ( isdigit( *temp ) ) + temp++; + allDigits = *temp == '.'; + } + + if ( e.type() == Object || allDigits ){ + e.embeddedObject().getFieldsDotted( next , ret ); + } + else if ( e.type() == Array ){ + BSONObjIterator j( e.embeddedObject() ); + while ( j.more() ){ + BSONElement f = j.next(); if ( f.type() == Object ) - f.embeddedObject().getFieldsDotted(p+1, ret); + f.embeddedObject().getFieldsDotted( next , ret ); } - } else if ( e.type() == Object ) { - e.embeddedObject().getFieldsDotted(p+1, ret); } + else { + // intentially left blank, this means no match + } + return; } - } else { - if ( e.type() == Array ) { - trueDat( deep ); - BSONObjIterator i( e.embeddedObject() ); - while( i.moreWithEOO() ) { - BSONElement f = i.next(); - if ( f.eoo() ) - break; - ret.insert( f ); + + case SAME: { + if ( e.type() == Array ){ + BSONObjIterator j( e.embeddedObject() ); + while ( j.more() ) + ret.insert( j.next() ); } - } else { - ret.insert( e ); + else { + ret.insert( e ); + } + return; + } + } } - if ( ret.empty() && deep ) - *deep = false; } BSONElement BSONObj::getFieldDottedOrArray(const char *&name) const { diff --git a/db/jsobj.h b/db/jsobj.h index 033a637976f..aaf059b6ff7 100644 --- a/db/jsobj.h +++ b/db/jsobj.h @@ -780,7 +780,7 @@ namespace mongo { BSONElement getFieldDotted(const char *name) const; /** Like getFieldDotted(), but expands multikey arrays and returns all matching objects */ - void getFieldsDotted(const char *name, BSONElementSet &ret, bool *deep = 0) const; + void getFieldsDotted(const char *name, BSONElementSet &ret ) const; /** Like getFieldDotted(), but returns first array encountered while traversing the dotted fields of name. The name variable is updated to represent field names with respect to the returned element. */ diff --git a/jstests/regex_embed1.js b/jstests/regex_embed1.js new file mode 100644 index 00000000000..61b1b9a14f6 --- /dev/null +++ b/jstests/regex_embed1.js @@ -0,0 +1,25 @@ + +t = db.regex_embed1 + +t.drop() + +t.insert( { _id : 1 , a : [ { x : "abc" } , { x : "def" } ] } ) +t.insert( { _id : 2 , a : [ { x : "ab" } , { x : "de" } ] } ) +t.insert( { _id : 3 , a : [ { x : "ab" } , { x : "de" } , { x : "abc" } ] } ) + +function test( m ){ + assert.eq( 3 , t.find().itcount() , m + "1" ); + assert.eq( 2 , t.find( { "a.x" : "abc" } ).itcount() , m + "2" ); + assert.eq( 2 , t.find( { "a.x" : /.*abc.*/ } ).itcount() , m + "3" ); + + assert.eq( 1 , t.find( { "a.0.x" : "abc" } ).itcount() , m + "4" ); + assert.eq( 1 , t.find( { "a.0.x" : /abc/ } ).itcount() , m + "5" ); +} + +test( "A" ); + +t.ensureIndex( { "a.x" : 1 } ) +test( "B" ); + + + |