Skip to content

Commit

Permalink
added; support for mongodb 2.4 geojson
Browse files Browse the repository at this point in the history
  • Loading branch information
aheckmann committed Feb 26, 2013
1 parent 28de236 commit 9b9dc92
Show file tree
Hide file tree
Showing 6 changed files with 346 additions and 68 deletions.
97 changes: 94 additions & 3 deletions lib/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ function Query (criteria, options) {
this._conditions = {};
this._updateArg = {};
this._fields = undefined;
this._geoComparison = undefined;
if (criteria) this.find(criteria);
}

Expand Down Expand Up @@ -301,7 +302,8 @@ Query.prototype.cast = function (model, obj) {

var geo = val.$near ? '$near' :
val.$nearSphere ? '$nearSphere' :
val.$within ? '$within' : '';
val.$within ? '$within' :
val.$geoIntersects ? '$geoIntersects' : '';

if (!geo) {
continue;
Expand All @@ -316,12 +318,23 @@ Query.prototype.cast = function (model, obj) {

if ('$within' == geo) {
// find $center, $centerSphere, $box, $polygon
var withinType = value.$center || value.$centerSphere || value.$box || value.$polygon;
var withinType = value.$center || value.$centerSphere || value.$box || value.$polygon// || value.$geometry;
if (!withinType) {
throw new Error('Bad $within paramater: ' + JSON.stringify(val));
}

value = withinType;

} else if ('$near' == geo &&
'string' == typeof value.type && Array.isArray(value.coordinates)) {
// geojson; cast the coordinates
value = value.coordinates;

} else if (('$near' == geo || '$geoIntersects' == geo) &&
value.$geometry && 'string' == typeof value.$geometry.type &&
Array.isArray(value.$geometry.coordinates)) {
// geojson; cast the coordinates
value = value.$geometry.coordinates;
}

;(function _cast (val) {
Expand Down Expand Up @@ -976,7 +989,34 @@ Query.prototype.elemMatch = function (path, criteria) {
*/

Object.defineProperty(Query.prototype, 'within', {
get: function () { return this }
get: function () {
this._geoComparison = '$within';
return this
}
});

/**
* Declares an intersects query for `geometry()`.
*
* ####Example
*
* query.intersects.geometry({
* type: 'LineString'
* , coordinates: [[180.0, 11.0], [180, 9.0]]
* })
*
* @property intersects
* @see Query#geometry #query_Query-geometry
* @memberOf Query
* @return {Query} this
* @api public
*/

Object.defineProperty(Query.prototype, 'intersects', {
get: function () {
this._geoComparison = '$geoIntersects';
return this
}
});

/**
Expand Down Expand Up @@ -1092,6 +1132,57 @@ Query.prototype.polygon = function (path, val) {
return this;
};

/**
* Specifies a $geometry condition
*
* Accepts an object that must contain the following two properties:
*
* - type: `String`
* - coordinates: `Array`
*
* ####Example
*
* var polyA = [[[ 10, 20 ], [ 10, 40 ], [ 30, 40 ], [ 30, 20 ]]]
* query.where('loc').within.geometry({ type: 'Polygon', coordinates: polyA })
*
* // or
* var polyB = [[ 0, 0 ], [ 1, 1 ]]
* query.where('loc').within.geometry({ type: 'LineString', coordinates: polyB })
*
* // or
* var polyC = [ 0, 0 ]
* query.where('loc').within.geometry({ type: 'Point', coordinates: polyC })
*
* // or
* var polyC = [ 0, 0 ]
* query.where('loc').intersects.geometry({ type: 'Point', coordinates: polyC })
*
* _NOTE: Must come after `intersects` or `within`._
*
* @param {String} [path]
* @param {Object} obj
* @return {Query} this
* @see http://docs.mongodb.org/manual/release-notes/2.4/#new-geospatial-indexes-with-geojson-and-improved-spherical-geometry
* @see http://www.mongodb.org/display/DOCS/Geospatial+Indexing
* @api public
*/

Query.prototype.geometry = function (path, val) {
if (arguments.length === 1) {
val = path;
path = this._currPath;
}

var conds = this._conditions[path] || (this._conditions[path] = {});

if (!this._geoComparison) {
throw new Error('query.geometry() must come after either `within` or `intersects`');
}

conds[this._geoComparison] = { $geometry: val };
return this;
};

/**
* Specifies which document fields to include or exclude
*
Expand Down
10 changes: 5 additions & 5 deletions lib/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,10 +675,10 @@ Schema.prototype.get = function (key) {

Schema.prototype.indexes = function () {
var indexes = []
, seenSchemas = [];
, seenSchemas = []
, indexTypes = '2d 2dsphere'.split(' ');

collectIndexes(this);

return indexes;

function collectIndexes (schema, prefix) {
Expand All @@ -696,10 +696,10 @@ Schema.prototype.indexes = function () {
} else {
index = paths[i]._index;

if (index !== false && index !== null){
if (index !== false && index !== null) {
var field = {};
field[prefix + i] = '2d' === index ? index : 1;
var options = 'Object' === index.constructor.name ? index : {};
field[prefix + i] = ~indexTypes.indexOf(index) ? index : 1;
var options = utils.isObject(index) ? index : {};
if (!('background' in options)) options.background = true;
indexes.push([field, options]);
}
Expand Down
38 changes: 38 additions & 0 deletions lib/schema/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,18 @@ function castToNumber (val) {
return Types.Number.prototype.cast.call(this, val);
}

function castArray (arr, self) {
self || (self = this);

arr.forEach(function (v, i) {
if (Array.isArray(v)) {
castArray(v, self);
} else {
arr[i] = castToNumber.call(self, v);
}
});
}

SchemaArray.prototype.$conditionalHandlers = {
'$all': function handle$all (val) {
if (!Array.isArray(val)) {
Expand Down Expand Up @@ -255,10 +267,36 @@ SchemaArray.prototype.$conditionalHandlers = {
val[type][i] = castToNumber.call(this, item);
}
})
} else if (val.$geometry) {
switch (val.$geometry.type) {
case 'Polygon':
case 'LineString':
case 'Point':
val.$geometry.coordinates.forEach(castArray);
break;
default:
// ignore unknowns
break;
}
}

return val;
}
, '$geoIntersects': function (val) {
var geo = val.$geometry;
if (!geo) return;

switch (val.$geometry.type) {
case 'Polygon':
case 'LineString':
case 'Point':
val.$geometry.coordinates.forEach(castArray);
break;
default:
// ignore unknowns
break;
}
}
, '$maxDistance': castToNumber
};

Expand Down
2 changes: 1 addition & 1 deletion lib/schema/number.js
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ function handleSingle (val) {

function handleArray (val) {
var self = this;
return val.map( function (m) {
return val.map(function (m) {
return self.cast(m)
});
}
Expand Down
23 changes: 22 additions & 1 deletion test/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,28 @@ module.exports = function (options) {
};

/**
* Module exports.
* expose mongoose
*/

module.exports.mongoose = mongoose;

/**
* expose mongod version helper
*/

module.exports.mongodVersion = function (cb) {
var db = module.exports();

db.on('error', cb);

db.on('open', function () {
db.db.admin(function (err, admin) {
if (err) return cb(err);
admin.serverStatus(function (err, info) {
if (err) return cb(err);
var version = info.version.split('.').map(function(n){return parseInt(n, 10) });
cb(null, version);
});
});
})
}
Loading

0 comments on commit 9b9dc92

Please sign in to comment.