与geonear的mongoose聚合

我试图用Mongoose geoNear命令实现分页。 它似乎跳过不支持与geoNear,我明白聚合将工作(与分页与性能成本)。 我怎样才能转换为聚合查询跳过一些文件?

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 to kilometers. (The radius of the Earth is 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 }); } }; 

你可以使用这个聚合框架,因为操作本质上是一样的,所以没有真正的惩罚。

但是,当.find()方法目前与$nearSphere运算符有相同的问题时,您可以始终抓取原始节点驱动程序连接对象并进行查询。

如果你准备实施一点处理,你甚至不需要扔掉像“人口”这样的东西。

这是我的testing数据:

 { "_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") } 

和处理这个基本的代码:

 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 ) ); }); }); } ); 

所以你可以在游标上使用skiplimit操作,返回一个游标,甚至把文档处理回“Mongoose Documents”,这样你可以调用像.populate()这样的函数。

不过,我认为目前与$nearSphere有关的问题很快就会得到解决。

或者使用聚合代替:

 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; return new Shape( x ); }); Shape.populate( shapes, { path: "info" }, function(err,docs) { if (err) throw err; console.log( JSON.stringify( docs, undefined, 4 ) ); }); } ); 

在哪里可以做同样的事情,比如use .populate() 。 这两种情况都会返回像这样匹配的“填充”字段的结果:

 { "_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 ] } } 

当然,如果你不需要球面几何计算,那么$near操作符在Mongoose实现.find()

 location.aggregate({"$geoNear": { "near": { "type": "Point", "coordinates": [parseFloat(req.params.lon), parseFloat(req.params.lat)] }, "maxDistance":500, 'distanceField' : 'distance', spherical: true }}, function(err, places) { if(!err){ console.log(places); res.send('({"records":' + JSON.stringify(places) + '});'); } else{ console.log(err); res.send("error coming") } });` Above Query working fine in mongo shell but not working in mongoose