我们有一个模型事件,其中包含“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
});
});
答案 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或英里)。
我在写这篇文章的过程中发现kmFrom
和milesFrom
的当前实现已被破坏。 npm上的最新版本有这个破解的代码。 The functions have been updated on GitHub(你可以看到少量的代码可以在本地进行更改以使它们正常工作),但在撰写本文时它尚未被推送到Keystone的版本中。