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

Mongoose 如何将“距离”注入到位置列表中,mongoose,keystonejs,Mongoose,Keystonejs,我们有一个具有字段的模型事件 我们想要实现的是:给定一个lat/lon坐标附近的查询,我们希望列表中的每个结果也有一个称为“距离”的字段,即从提供的坐标到结果集中每个对象的location.geo的距离(以km为单位) 我们在KeystoneJS位置类型定义中看到了 但是我们不知道如何为列表中的每个结果将其作为虚拟对象注入 有人知道如何将请求的Lat/Lon传递给那些下划线方法并将其填充到结果列表中吗 var q = Event.paginate({ page: req.query.page |

我们有一个具有字段的模型事件

我们想要实现的是:给定一个lat/lon坐标附近的查询,我们希望列表中的每个结果也有一个称为“距离”的字段,即从提供的坐标到结果集中每个对象的location.geo的距离(以km为单位)

我们在KeystoneJS位置类型定义中看到了

但是我们不知道如何为列表中的每个结果将其作为虚拟对象注入

有人知道如何将请求的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项可以具有充当文档函数的方法。虚拟函数不接受用于根据文档属性计算/返回值的参数。因此,这里需要一个模式方法

在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上的最新版本有这样的代码。您可以看到少量代码需要在本地进行更改,这将使它们正常工作,但在撰写本文时,还没有将其发布到Keystone中。

非常有用,非常感谢您的回复。我还认为问题的一部分是.paginate函数,它基于我所看到的内容,不会将列表项作为模型对象返回,因此当我迭代items.results中的对象时,我的模型方法不起作用。我们需要更深入地研究这个问题。