summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron <aaron@10gen.com>2010-03-22 10:53:06 -0700
committerAaron <aaron@10gen.com>2010-03-22 10:53:06 -0700
commit5d7f77dda7126caacd4823c180ba59cd28a435f8 (patch)
treec85b91f83e7594d38c9bea233b259b62b2219ab9
parent82be9226a67a465e62615d088c90d6085f9e841d (diff)
parent254f59877e4402c510914a7ba7025dbdbe504e6d (diff)
downloadmongo-5d7f77dda7126caacd4823c180ba59cd28a435f8.tar.gz
Merge branch 'master' of github.com:mongodb/mongo
-rw-r--r--db/jsobj.cpp83
-rw-r--r--db/jsobj.h2
-rw-r--r--jstests/regex_embed1.js25
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" );
+
+
+