Matteo Muratori
unread,Mar 28, 2011, 11:17:03 AM3/28/11Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to node-mongodb-native
As far as I know, the geoNear command (supported by latest MongoDB
versions) has not been already added to the great node-mongodb-native
driver.
After writing to Christian Amor Kvalheim (the node-mongodb-native
driver author), I've decided to post my geoNear command
implementation, because he never answered me about a possible
integration.
So here's my geoNear code, wishing that some other node-mongodb-native
developer could integrate it in the official branch.
The code could be (should be) improved in order to use the Cursor
class for the geoNear results; at the moment returned values are
stored in memory all together.
/**
* Execute the geoNear command; this command has the added benefit
(respect to the find command) of returning the distance of each item
from the specified point in the results.
*
* @param options Options can be:
* near: [x, y]
* spherical: true/false
* maxDistance: number, it scales the distance returned as 'dis' in
the result documents
* distanceMultiplier: number, all distances results (i.e. .dis
field) are scaled by this factor
* num: limit number of returned documents
* query: additional query filter
*
* @param callback {function(Error, Array<Object>)} This will be called
after executing this method successfully.
* The first paramter will contain the Error object if an error
occured, or null otherwise.
* The second paramter will contain an array of documents: each
document has the following format:
* {
* 'dis': the distance (with maxDistance already applied)
* 'obj': the real database document
* }
*
* Example: collection.geoNear({ 'near': [44.6, 12.71], 'spherical':
true, 'maxDistance': 10.2, 'distanceMultiplier': 6378160.0, 'num': 5,
'query': { 'type': 'museum' } }, function(err, docs) { ... });
*
*/
var QueryCommand = require('mongodb').QueryCommand,
DbCommand = require('mongodb').DbCommand,
Collection = require('mongodb').Collection;
Collection.prototype.geoNear = function(options, callback) {
var command;
var selector = {
'geoNear': this.collectionName
};
callback = callback || function(err, docs) {};
if (options) {
// near
if (options.near && options.near instanceof Array &&
options.near.length > 1)
selector.near = [options.near[0], options.near[1]];
// spherical
options.spherical ? selector.spherical = true :
selector.spherical = false;
// maxDistance
if (options.maxDistance && typeof options.maxDistance ==
'number')
selector.maxDistance = options.maxDistance;
// distanceMultiplier
if (options.distanceMultiplier && typeof
options.distanceMultiplier == 'number')
selector.distanceMultiplier = options.distanceMultiplier;
// num
if (options.num && typeof options.num == 'number')
selector.num = options.num;
// query
if (options.query)
selector.query = options.query;
}
// build the db command
command = new DbCommand(this.db, this.db.databaseName + '.' +
DbCommand.SYSTEM_COMMAND_COLLECTION,
QueryCommand.OPTS_NO_CURSOR_TIMEOUT, 0, -1, selector, null);
// execute the command
this.db.executeCommand(command, function(err, result) {
if (err == null && result.documents[0].ok == 1)
// pass documents to the callback
callback(null, result.documents[0].results);
else
// report the error
err != null ? callback(err, null) : callback(new
Error(result.documents[0].errmsg), null);
});
}
Have fun!
Matteo.