如何将 "distance" 注入位置列表
How to inject "distance" into a list of Locations
我们有一个具有“Location”字段的模型事件。
我们想要实现的是:给定一个 lat/lon 坐标附近的查询,我们希望列表中的每个结果也有一个字段,称为 distance
,即距结果集中每个对象的 location.geo
坐标。
我们在KeystoneJS Location类型定义中看到有underscore methods for this.
但我们无法弄清楚如何将其作为列表中每个结果的 "virtual" 注入。
有没有人知道如何将请求的 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
});
});
KeystoneJS 项目可以具有充当文档功能的方法。虚函数不接受参数(它们用于 calculate/return 基于文档属性的值)。所以这里需要一个模式上的方法。
在您的 Event.js
模型代码中,您需要创建适当的方法来根据存储在当前文档中的坐标计算距离(以公里为单位)。
Event.schema.methods.distanceKM = function (latitude, longitude, cb) {
return cb(this._.location.kmFrom([longitude, latitude]));
};
这是一个异步实现。如果您t/don不想那样做,请改用它。
Event.schema.methods.distanceKM = function (latitude, longitude) {
return this._.location.kmFrom([longitude, latitude]);
};
如果您需要结果以英里为单位,只需将方法中的 kmFrom
更改为 milesFrom
。
然后您可以为每个事件调用距离函数。具体的实现取决于您,但是下面的查询返回的每个项目现在都将具有 distance
函数,该函数 returns 从该事件到参数化的距离(公里或英里)坐标.
重要
我在写这篇文章的过程中发现 kmFrom
和 milesFrom
的当前实现被破坏了。 npm 上的最新版本有这个损坏的代码。 The functions have been updated on GitHub(您可以看到在本地更改的少量代码将使它们工作),但在撰写本文时尚未将其推送到 Keystone 版本中。
我们有一个具有“Location”字段的模型事件。
我们想要实现的是:给定一个 lat/lon 坐标附近的查询,我们希望列表中的每个结果也有一个字段,称为 distance
,即距结果集中每个对象的 location.geo
坐标。
我们在KeystoneJS Location类型定义中看到有underscore methods for this.
但我们无法弄清楚如何将其作为列表中每个结果的 "virtual" 注入。
有没有人知道如何将请求的 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
});
});
KeystoneJS 项目可以具有充当文档功能的方法。虚函数不接受参数(它们用于 calculate/return 基于文档属性的值)。所以这里需要一个模式上的方法。
在您的 Event.js
模型代码中,您需要创建适当的方法来根据存储在当前文档中的坐标计算距离(以公里为单位)。
Event.schema.methods.distanceKM = function (latitude, longitude, cb) {
return cb(this._.location.kmFrom([longitude, latitude]));
};
这是一个异步实现。如果您t/don不想那样做,请改用它。
Event.schema.methods.distanceKM = function (latitude, longitude) {
return this._.location.kmFrom([longitude, latitude]);
};
如果您需要结果以英里为单位,只需将方法中的 kmFrom
更改为 milesFrom
。
然后您可以为每个事件调用距离函数。具体的实现取决于您,但是下面的查询返回的每个项目现在都将具有 distance
函数,该函数 returns 从该事件到参数化的距离(公里或英里)坐标.
重要
我在写这篇文章的过程中发现 kmFrom
和 milesFrom
的当前实现被破坏了。 npm 上的最新版本有这个损坏的代码。 The functions have been updated on GitHub(您可以看到在本地更改的少量代码将使它们工作),但在撰写本文时尚未将其推送到 Keystone 版本中。