如何将“距离”注入位置列表

时间:2017-03-21 18:47:53

标签: mongoose keystonejs

我们有一个模型事件,其中包含“Location”字段。

我们想要实现的是:给定一个纬度/经度坐标附近的查询,我们希望列表中的每个结果也有一个名为distance的字段,即从提供的坐标到公里的距离结果集中每个对象的location.geo

我们在KeystoneJS位置类型定义中看到underscore methods for this

但我们无法弄清楚如何将此注入为列表中每个结果的“虚拟”。

有没有人对如何将请求的Lat / Lon传递给那些下划线方法并在结果列表中填充它有任何想法?

var q = Event.paginate({ page: req.query.page || 1, perPage: req.query.max || 20 })
                         .where('eventDate').gt(since)
                         .where('state').equals('published')
                         .sort("eventDate")

if (req.query.lon && req.query.lat) {
    var coords = [req.query.lon, req.query.lat];
    var maxD = (req.query.maxDistance || 5) / 6371;
    q = q.where('location.geo')
             .near({ center: coords, maxDistance: maxD, spherical:true })
}
q.exec(function(err, items) {
    if (err) return res.apiError('database error', err);
    res.apiResponse({
        events: items
    });
});

1 个答案:

答案 0 :(得分:1)

KeystoneJS项目可以具有充当文档功能的方法。虚函数不接受参数(它们用于根据文档的属性计算/返回值)。因此,这里需要一个关于模式的方法。

Event.js模型代码中,您需要创建适当的方法,根据当前文档中存储的坐标计算距离(以千米为单位)。

Event.schema.methods.distanceKM = function (latitude, longitude, cb) {
    return cb(this._.location.kmFrom([longitude, latitude]));
};

这是一个异步实现。如果您不想/不希望这样做,请改用它。

Event.schema.methods.distanceKM = function (latitude, longitude) {
    return this._.location.kmFrom([longitude, latitude]);
};

如果您需要将结果设置为里程,请在方法中将kmFrom更改为milesFrom

然后,您可以为每个事件调用距离函数。该实现取决于您,但下面的查询返回的每个项目现在都具有distance函数,该函数返回从该事件到参数化坐标的距离(km或英里)。

重要

我在写这篇文章的过程中发现kmFrommilesFrom的当前实现已被破坏。 npm上的最新版本有这个破解的代码。 The functions have been updated on GitHub(你可以看到少量的代码可以在本地进行更改以使它们正常工作),但在撰写本文时它尚未被推送到Keystone的版本中。