1
我想这样做:
model.User.aggregate([
//step 1 match criteria
{
$match: criteria
},
//step 2 skip
{
$skip: offset
},
//step 3 limit
{
$limit: limit
},
//step 4 sort by computed distance
{
$geoNear : {
near: {type: 'Point', coordinates: coords },
distanceField: 'currentCity.computed_distance',
includeLocs: 'currentCity.loc',
spherical: true,
uniqueDocs: true,
distanceMultiplier: 3963.2, //convert to miles (this number is the radius of the earth in miles)
}
}
],function(err,users){
if (err) return res.error(err);
if (!users.length) return res.error('no matched criteria');
res.apiResponse(users);
});
但$ geoNear的文档状态:
您只能使用$ geoNear作为管道的第一阶段。
阅读该文档,我知道我可以在里面$geoNear
通过query
选项只需移动$match
。同样,$limit
可能通过limit
选项放置在$geoNear
的内部。一个问题是,$skip
选项没有等效,所以看起来好像无法实现分页功能?我真的很困惑,为什么$geoNear
不能成为第四步。查询的目的是简单地找到最好的n
匹配,其中n = limit
,然后按距离最近排序。这甚至有可能吗?我无法找到这个特定用例的答案。
我想一个解决方案可能是有$in
查询像这样执行查询只选择IDS匹配的文档,转换为ID的列表,然后做骨料:
model.User.find(criteria).skip(offset).limit(limit).select('_id').exec(function (err, userIds) {
var ids = [];
userIds.forEach(function(u){
ids.push(u._id);
});
model.User.aggregate([
{
$geoNear : {
query: { _id: {$in: $ids } },
near: {type: 'Point', coordinates: coords },
distanceField: 'currentCity.computed_distance',
includeLocs: 'currentCity.loc',
spherical: true,
uniqueDocs: true,
distanceMultiplier: 3963.2, //convert to miles (this number is the radius of the earth in miles)
}
}
],function(err,users){
if (err) return res.error(err);
if (!users.length) return res.error('no matched criteria');
res.apiResponse(users);
});
});
这会工作,但理想情况下,如果可能,我可以在1个查询中完成。任何想法非常赞赏。