使用Meteor.js我已经为我的酒吧/子工作完美地完成了以下代码。我能够通过我的论点并毫无问题地返回游标。
我的目标是显示当前用户位置和数据库结果之间的距离。
由于mongodb已经计算了获得结果集的距离,我不想再在其他地方计算它。我想返回$ geoNear记录的here的geoNear.results [n] .dis结果,但无法找到实用的方法。我很欣赏发布只返回一个光标到文档,但想知道是否有某种方法以某种方式附加结果......
Meteor.publishComposite("public", function(location, distance) {
return {
find: function() {
return Tutors.find({},
{
$geoNear: {
$geometry: {
type: "Point" ,
coordinates: [ location.lng , location.lat ]
},
$maxDistance: distance,
},
}
);
}
}
});
我的订阅参数只是一个lat / lng对象,以米为单位的距离。
答案 0 :(得分:1)
如果我告诉您可以使用Mongo aggregation 怎么办?这里的一般想法是通过'Tutors'
集合中的更改自动更新当前用户位置和数据库结果之间的距离,从而使用 publication
进行观察为达到这个。
这是设置。第一步是获取聚合框架包,它包含一些Mongo方法。只需meteor add meteorhacks:aggregate
你就应该回家干。这会为您的馆藏添加 aggregate()
方法。
添加聚合框架支持的另一种方法是直接调用mongoDB并访问底层集合方法,在这种情况下,您需要 aggregate()
方法。因此,使用它来连接mongoDB:
var db = MongoInternals.defaultRemoteCollectionDriver().mongo.db,
Tutors = db.collection("tutors");
现在您可以深入了解聚合框架并构建管道查询。以下示例演示了如何使用 observe
在发布中使用 ES6 in Meteor
获取发布被动聚合。这遵循流星文档中的'counts-by-room'
example 。使用 observe
,您知道是否添加,更改或删除了新位置。为简单起见,每次重新运行聚合(删除除外),如果位置先前已发布,则 update
发布,如果位置已删除,则 remove
来自发布的位置,然后使用新位置 added
:
Meteor.publish('findNearestTutors', function(opts) {
let initializing = 1, run = (action) => {
// Define the aggregation pipeline
let pipeline = [
{
$geoNear: {
near: {type: 'Point', coordinates: [Number(opts.lng), Number(opts.lat)]},
distanceField: 'distance',
maxDistance: opts.distance,
spherical: true,
sort: -1
}
}
]
Tutors.aggregate(pipeline).forEach((location) => {
// Add each of the results to the subscription.
this[action]('nearest-locations', location._id, location)
this.ready()
})
}
// Run the aggregation initially to add some data to your aggregation collection
run('added')
// Track any changes on the collection you are going to use for aggregation
let handle = Tutors.find({}).observeChanges({
added(id) {
// observeChanges only returns after the initial `added` callbacks
// have run. Until then, you don't want to send a lot of
// `self.changed()` messages - hence tracking the
// `initializing` state.
if (initializing && initializing--)
run('changed')
},
removed(id) {
run('changed')
},
changed(id) {
run('changed')
},
error(err) {
throw new Meteor.Error("Houston, we've got a problem here!", err.message)
}
})
// Stop observing the cursor when client unsubs.
// Stopping a subscription automatically takes
// care of sending the client any removed messages.
this.onStop(function () {
handle.stop();
})
})