node.js - Mongoose aggregation with geonear -
node.js - Mongoose aggregation with geonear -
i'm trying implement paging mongoose geonear command. seem skip not supported geonear, , understand aggregation work (with paging performance cost). how can convert aggregation query skip number of documents?
exports.near = function(req, res) { if(req.query.lat && req.query.lng) { var point = { type: "point", coordinates : [number(req.query.lng), number(req.query.lat)] }; var queryparams = { spherical: true, skip: 0, limit: 10, distancemultiplier: 6371 // radians kilometers. (the radius of earth approximately 3,959 miles or 6,371 kilometers.) }; if(req.query.q) { var matcher = new regexp(req.query.q, "i"); queryparams.query = { $or: [ {'name': matcher }, {'address.full': matcher} ] }; } if(req.query.limit) { queryparams.limit = parseint(req.query.limit, 10); } if(req.query.offset) { queryparams.skip = parseint(req.query.offset, 10); } venue.geonear(point, queryparams, function(error, results, stats) { // todo }); } };
you can utilize aggregation framework , there no real penalty operations same.
but while mongoose .find()
method presently has problem $nearsphere
operator equivalent, can grab raw node driver connection object , query.
you not need throw away things "population" if prepared implement little handling.
here test data:
{ "_id" : "p1", "amenity" : "restaurant", "shape" : { "type" : "point", "coordinates" : [ 2, 2 ] } } { "_id" : "p3", "amenity" : "police", "shape" : { "type" : "point", "coordinates" : [ 4, 2 ] } } { "_id" : "p4", "amenity" : "police", "shape" : { "type" : "point", "coordinates" : [ 4, 4 ] } } { "_id" : "p2", "amenity" : "restaurant", "shape" : { "type" : "point", "coordinates" : [ 2, 4 ] }, "info" : objectid("539b90543249ff8d18e863fb") }
and basic code handle this:
var mongoose = require('mongoose'), async = require('async'), schema = mongoose.schema; mongoose.connect('mongodb://localhost'); var infoschema = new schema({ "description": string }); var shapeschema = new schema({ "_id": string, "amenity": string, "shape": { "type": { "type": string }, "coordinates": [] }, "info": { "type": schema.types.objectid, "ref": "info" } }); var shape = mongoose.model( "shape", shapeschema ); var info = mongoose.model( "info", infoschema ); shape.collection.find( { "shape": { "$nearsphere": { "$geometry": { "type": "point", "coordinates": [ 2, 4 ] } } } }, { "skip": 0, "limit": 2 }, function(err,cursor) { cursor.toarray(function(err,shapes) { shape.populate( shapes, { path: "info" }, function(err,docs) { if (err) throw err; console.log( json.stringify( docs, undefined, 4 ) ); }); }); } );
so there got usage of both skip , limit operations on cursor, had cursor returned , processed documents "mongoose documents" can phone call functions .populate()
on them.
i expect current issue $nearsphere
fixed relatively though.
or using aggregate instead:
shape.aggregate( [ { "$geonear": { "near": { "type": "point", "coordinates": [ 2, 4 ] }, "spherical": true, "distancefield": "dis" }}, { "$skip": 0 }, { "$limit": 2 } ], function(err,shapes) { if (err) throw err; //console.log( shapes ); shapes = shapes.map(function(x) { delete x.dis; homecoming new shape( x ); }); shape.populate( shapes, { path: "info" }, function(err,docs) { if (err) throw err; console.log( json.stringify( docs, undefined, 4 ) ); }); } );
where can same things such utilize .populate()
. both cases homecoming results "populated" field matched:
{ "_id": "p2", "amenity": "restaurant", "info": { "_id": "539b90543249ff8d18e863fb", "description": "jamies restaurant", "__v": 0 }, "shape": { "type": "point", "coordinates": [ 2, 4 ] } }, { "info": null, "_id": "p4", "amenity": "police", "shape": { "type": "point", "coordinates": [ 4, 4 ] } }
of course of study if not need spherical geometry calculation $near
operator works fine mongoose implementation of .find()
node.js mongodb mongoose geospatial aggregation-framework
Comments
Post a Comment