| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 | 
							- "use strict";
 
- var DocumentSource = require("./DocumentSource"),
 
- 	FieldPath = require("../FieldPath");
 
- /**
 
-  * @class GeoNearDocumentSource
 
-  * @namespace mungedb-aggregate.pipeline.documentSources
 
-  * @module mungedb-aggregate
 
-  * @constructor
 
-  * @param [ctx] {ExpressionContext}
 
-  **/
 
- var GeoNearDocumentSource = module.exports = function GeoNearDocumentSource(ctx) {
 
- 	if (arguments.length > 1) throw new Error("up to one arg expected");
 
- 	base.call(this, ctx);
 
- 	// mongo defaults
 
- 	this.coordsIsArray = false;
 
- 	this.limit = 100;
 
- 	this.maxDistance = -1.0;
 
- 	this.spherical = false;
 
- 	this.distanceMultiplier = 1.0;
 
- 	this.uniqueDocs = true;
 
- }, klass = GeoNearDocumentSource, base = require("./DocumentSource"), proto = klass.prototype = Object.create(base.prototype, {constructor:{value:klass}}); //jshint ignore:line
 
- klass.geoNearName = "$geoNear";
 
- klass.create = function create(expCtx) {
 
- 	return new GeoNearDocumentSource(expCtx);
 
- };
 
- proto.getSourceName = function() {
 
- 	return klass.geoNearName;
 
- };
 
- proto.getNext = function getNext() {
 
- 	throw new Error("Not implemented yet");
 
- };
 
- proto.setSource = function(docSource) {
 
- 	throw new Error("code 16602; $geoNear is only allowed as the first pipeline stage");
 
- };
 
- proto.isValidInitialSource = function() {
 
- 	return true;
 
- };
 
- proto.serialize = function(explain) {
 
- 	var result = {};
 
- 	if (this.coordsIsArray)
 
- 		result.near = this.near;
 
- 	else
 
- 		result.near = [this.near];
 
- 	// not in buildGeoNearCmd
 
- 	result.distanceField = this.distanceField.getPath(false);
 
- 	result.limit = this.limit;
 
- 	if (this.maxDistance > 0)
 
- 		result.maxDistance = this.maxDistance;
 
- 	if (this.query)
 
- 		result.query = this.query;
 
- 	if (this.spherical)
 
- 		result.spherical = this.spherical;
 
- 	if (this.distanceMultiplier)
 
- 		result.distanceMultiplier = this.distanceMultiplier;
 
- 	if (this.includeLocs) {
 
- 		if (typeof this.includeLocs !== "string")
 
- 			throw new Error("code 16607; $geoNear requires that \"includeLocs\" option is a String");
 
- 		result.includeLocs = this.includeLocs.getPath(false);
 
- 	}
 
- 	if (this.uniqueDocs)
 
- 		result.uniqueDocs = this.uniqueDocs;
 
- 	var sourceName = this.getSourceName(),
 
- 		returnObj = {};
 
- 	returnObj[sourceName] = result;
 
- 	return returnObj;
 
- };
 
- klass.createFromJson = function(jsonElement, ctx) {
 
- 	var out = new GeoNearDocumentSource(ctx);
 
- 	out.parseOptions(jsonElement);
 
- 	return out;
 
- };
 
- proto.parseOptions = function(options) {
 
- 	// near and distanceField are required
 
- 	if (!options.near || !Array.isArray(options.near))
 
- 		throw new Error("code 16605; $geoNear requires a \"near\" option as an Array");
 
- 	this.coordsIsArray = options.near instanceof Array;
 
- 	if (typeof options.distanceField !== "string")
 
- 		throw new Error("code 16606: $geoNear  a \"distanceNear\" option as a String");
 
- 	this.distanceField = new FieldPath(options.distanceField);
 
- 	// remaining fields are optional
 
- 	// num and limits are synonyms
 
- 	if (typeof options.limit === "number")
 
- 		this.limit = options.limit;
 
- 	if (typeof options.num === "number")
 
- 		this.limit = options.num;
 
- 	if (typeof options.maxDistance === "number")
 
- 		this.maxDistance = options.maxDistance;
 
- 	if (options.query instanceof Object)
 
- 		this.query = options.query;
 
- 	if (options.spherical)
 
- 		this.spherical = Boolean(options.spherical);
 
- 	if (typeof options.distanceMultiplier === "number")
 
- 		this.distanceMultiplier = options.distanceMultiplier;
 
- 	if (options.includeLocs) {
 
- 		if (typeof options.includeLocs !== "string")
 
- 			throw new Error("code 16607; $geoNear requires that \"includeLocs\" option is a String");
 
- 		this.includeLocs = new FieldPath(options.includeLocs);
 
- 	}
 
- 	if (options.uniqueDocs)
 
- 		this.uniqueDocs = Boolean(options.uniqueDocs);
 
- };
 
 
  |