| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 | 
							- var MatchDocumentSource = module.exports = (function(){
 
- 	// CONSTRUCTOR
 
- 	/**
 
- 	 * A match document source built off of FilterBaseDocumentSource
 
- 	 * Currently uses sift to fake it
 
- 	 * 
 
- 	 * @class MatchDocumentSource
 
- 	 * @namespace munge.pipeline.documentsource
 
- 	 * @module munge
 
- 	 * @constructor
 
- 	 * @param {Object} query the match query to use
 
- 	**/
 
- 	var klass = module.exports = MatchDocumentSource = function MatchDocumentSource(query /*, pCtx*/){
 
- 		if(arguments.length !== 1) throw new Error("one arg expected");
 
- 		base.call(this);
 
- 		this.matcher = sift(query);
 
- 	}, base = require('./FilterBaseDocumentSource'), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}});
 
- 	klass.extend = function extend(obj, withObj){
 
- 		var args = Array.prototype.slice.call(arguments), lastArg = args[args.length - 1]; 
 
- 		for(var i = 1, n = args.length; i < n; i++){
 
- 			withObj = args[i];
 
- 			for(var key in withObj){
 
- 				if(withObj.hasOwnProperty(key)){
 
- 					var objVal = obj[key], withObjVal = withObj[key];
 
- 					if(objVal instanceof Object && withObjVal.constructor === Object){
 
- 						klass.extend(objVal, withObjVal);
 
- 					}else{
 
- 						obj[key] = withObjVal;
 
- 					}
 
- 				}
 
- 			}
 
- 		}   
 
- 		return obj;
 
- 	};
 
- 	// DEPENDENCIES
 
- 	var sift = require("sift");
 
- 	klass.matchName = "$match";
 
- 	proto.getSourceName = function getSourceName(){
 
- 		return klass.matchName;
 
- 	};
 
-     /**
 
- 	 * Create an object that represents the document source.  The object
 
-      * will have a single field whose name is the source's name.  This
 
-      * will be used by the default implementation of addToJsonArray()
 
-      * to add this object to a pipeline being represented in JSON.
 
-      * 
 
-      * @method	sourceToJson
 
-      * @param	{Object} builder	JSONObjBuilder: a blank object builder to write to
 
-      * @param	{Boolean}	explain	create explain output
 
-     **/
 
- 	proto.sourceToJson = function sourceToJson(builder, explain) {
 
- 		builder[this.getSourceName()] = this.matcher.query;
 
- 	};
 
- 	/**
 
- 	* Test the given document against the predicate and report if it
 
- 	* should be accepted or not.
 
- 	*
 
- 	* @param {object} document the document to test
 
- 	* @returns {bool} true if the document matches the filter, false otherwise
 
- 	**/
 
- 	proto.accept = function accept(document) {
 
- 		/**
 
- 		* The matcher only takes BSON documents, so we have to make one.
 
- 		*
 
- 		* LATER
 
- 		* We could optimize this by making a document with only the
 
- 		* fields referenced by the Matcher.  We could do this by looking inside
 
- 		* the Matcher's BSON before it is created, and recording those.  The
 
- 		* easiest implementation might be to hold onto an ExpressionDocument
 
- 		* in here, and give that pDocument to create the created subset of
 
- 		* fields, and then convert that instead.
 
- 		**/
 
- 		return this.matcher.test(document);
 
- 	};
 
- 	/**
 
- 	* Create a JSONObj suitable for Matcher construction.
 
- 	*
 
- 	* This is used after filter analysis has moved as many filters to
 
- 	* as early a point as possible in the document processing pipeline.
 
- 	* See db/Matcher.h and the associated wiki documentation for the
 
- 	* format.  This conversion is used to move back to the low-level
 
- 	* find() Cursor mechanism.
 
- 	*
 
- 	* @param builder the builder to write to
 
- 	**/
 
- 	proto.toMatcherJson = function toMatcherJson(builder) {
 
- 		klass.extend(builder, this.matcher.query);
 
- 	};
 
- 	klass.uassertNoDisallowedClauses = function uassertNoDisallowedClauses(query) {
 
- 		for(var key in query){
 
- 			if(query.hasOwnProperty(key)){
 
- 				// can't use the Matcher API because this would segfault the constructor
 
- 				if ( query[key] == "$where") throw new Error("code 16395; $where is not allowed inside of a $match aggregation expression");
 
- 				// geo breaks if it is not the first portion of the pipeline
 
- 				if ( query[key] == "$near") throw new Error("code 16424; $near is not allowed inside of a $match aggregation expression");
 
- 				if ( query[key] == "$within") throw new Error("code 16425l $within is not allowed inside of a $match aggregation expression");
 
- 				if ( query[key] == "$nearSphere") throw new Error("code 16426; $nearSphere is not allowed inside of a $match aggregation expression");
 
- 				if(query[key] instanceof Object && query[key].constructor === Object)
 
- 					this.uassertNoDisallowedClauses(query[key]);
 
- 			}
 
- 		}
 
- 	}; 
 
- 	klass.createFromJson = function createFromJson(JsonElement) {
 
- 		if (!(JsonElement instanceof Object) || JsonElement.constructor !== Object) throw new Error("code 15959 ; the match filter must be an expression in an object");
 
- 		klass.uassertNoDisallowedClauses(JsonElement);
 
- 		var matcher = new MatchDocumentSource(JsonElement);
 
- 		return matcher;
 
- 	};
 
- 	return klass;
 
- })();
 
 
  |