|
|
@@ -92,30 +92,60 @@ proto.init = function init( path,type ) { // const StringData& path, int type
|
|
|
* @param
|
|
|
*
|
|
|
*/
|
|
|
-/*
|
|
|
+
|
|
|
proto.matches = function matches( doc,details ) { // const MatchableDocument* doc, MatchDetails* details
|
|
|
// File: expression_leaf.cpp lines: 318-332
|
|
|
-// bool TypeMatchExpression::matches( const MatchableDocument* doc, MatchDetails* details ) const {
|
|
|
-// boost::scoped_ptr<ElementIterator> cursor( doc->getIterator( _elementPath ) );
|
|
|
-// while ( cursor->more() ) {
|
|
|
-// ElementIterator::Context e = cursor->next();
|
|
|
-// if ( e.outerArray() )
|
|
|
-// continue;
|
|
|
-//
|
|
|
-// if ( !matchesSingleElement( e.element() ) )
|
|
|
-// continue;
|
|
|
-// if ( details && details->needRecord() && !e.arrayOffset().eoo() ) {
|
|
|
-// details->setElemMatchKey( e.arrayOffset().fieldName() );
|
|
|
-// }
|
|
|
-// return true;
|
|
|
-// }
|
|
|
-// return false;
|
|
|
-// }
|
|
|
- var tDoc = ElementPath.objAtPath( doc, this._path );
|
|
|
+ return this._matches(doc,this._path,details);
|
|
|
+};
|
|
|
+
|
|
|
+proto._matches = function _matches(doc,path,details) {
|
|
|
+ var element, k, item,
|
|
|
+ curr = doc;
|
|
|
+ for (k = 0; k < path.length; k++) {
|
|
|
+ item = curr[path[k]];
|
|
|
+ if (item instanceof Object && item.constructor === Object) {
|
|
|
+ curr = item;
|
|
|
+ continue;
|
|
|
+ } else if (item instanceof Object && item.constructor === Array) {
|
|
|
+ if (k == path.length-1) {
|
|
|
+ curr = item;
|
|
|
+ break; // this is the end of the path, so check this array
|
|
|
+ } else if (!(isNaN(parseInt(path[k+1], 10)))) {
|
|
|
+ curr = item;
|
|
|
+ continue; // the *next* path section is an item in the array so we don't check this whole array
|
|
|
+ }
|
|
|
+ // otherwise, check each item in the array against the rest of the path
|
|
|
+ for(var ii = 0, il = item.length; ii < il; ii++){
|
|
|
+ var subitem = item[ii];
|
|
|
+ if (subitem.constructor !== Object) continue; // can't look for a subfield in a non-object value.
|
|
|
+ if (this._matches(subitem, path.slice(k), null)) { // check the item against the rest of the path
|
|
|
+ if (details && details.needRecord())
|
|
|
+ details.setElemMatchKey(ii.toString());
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false; // checked all items in the array and found no matches
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // we got the whole path, now check it
|
|
|
+ element = item;
|
|
|
+
|
|
|
+ //var amIRoot = (element.length === 0);
|
|
|
+
|
|
|
+ if (!this.matchesSingleElement(element, details))
|
|
|
+ return false;
|
|
|
+
|
|
|
+ /*
|
|
|
+ if (!amIRoot && details && details.needRecord() {
|
|
|
+ details.setElemMatchKey(element);
|
|
|
+ }
|
|
|
+ */
|
|
|
+ return true;
|
|
|
+}
|
|
|
|
|
|
|
|
|
|
|
|
-};*/
|
|
|
|
|
|
klass.typeNumber = function typeNumber( e ){
|
|
|
if(e === undefined)
|
|
|
@@ -131,13 +161,13 @@ klass.typeNumber = function typeNumber( e ){
|
|
|
if(typeof(e) == 'object') {
|
|
|
if(e instanceof Array)
|
|
|
return 4;
|
|
|
- if(e instanceof Regexp)
|
|
|
+ if(e instanceof RegExp)
|
|
|
return 11;
|
|
|
if(e instanceof Date)
|
|
|
return 9;
|
|
|
if(e.constructor.name == 'MinKey')
|
|
|
return -1;
|
|
|
- if(e.construcor.name == 'MAxKey')
|
|
|
+ if(e.constructor.name == 'MAxKey')
|
|
|
return 127;
|
|
|
}
|
|
|
return 42; // Can't tell
|