【发布时间】:2017-06-07 14:45:17
【问题描述】:
我希望有人可以帮助我 - 我想使用地理查询填充子文档以对其进行排序:
我有这些模型(简化):
(很多文章):
var articleSchema = mongoose.Schema({
places: [{ type: mongoose.Schema.Types.ObjectId, ref: "places", required: false }],
someData: { type: String, required: true },
})
(很多地方):
var placeSchema = mongoose.Schema({
longitudelatitude: {
type: { type: String, required: true },
coordinates: [
{ type: Number, required: true }, //longitude
{ type: Number, required: true } //latitude
]},
someData: { type: String, required: true }
})
我第一个只查找位置附近的地方的查询工作正常:
getPlacesNearBy: function (lng, lat, skipNumber, limitNumber, callback) {
Place.find({
longitudelatitude: {
$near: {
$geometry: { type: "Point", coordinates: [lng, lat] },}}
}, null, {skip: skipNumber, limit: limitNumber}, function (err, foundPlaces) {
if (err)
return callback(err, null);
return callback(null, foundPlaces);
})
},
我可以找到我附近的地方 - 我可以选择有多少个 - 我可以用跳过重新加载更多
现在我想做类似的事情:
我想获得一篇文章 - 并填充存储的位置(您可以在哪里获得它们),然后我想按距离对位置进行排序,并可能跳过或限制响应
所以我尝试了:
getPlacesforArticle: function (articleId, lng, lat, skipNumber, limitNumber, callback) {
var projection = null;
Article.findById(articleId, {places: 1}).populate("places", projection, {
longitudelatitude: {
$near: {
$geometry: { type: "Point", coordinates: [lng, lat] },
}
}
}, {skip: skipNumber, limit: limitNumber}).exec(function (getError, foundArticle) {
if (getError)
return callback(getError, null);
callback(null, foundArticle.places);
});
}
},
所以这个查询正在工作(没有错误),但它没有响应我想要的 - 我得到了位置,但它们是由数据库序列而不是距离“排序”的 - 所以 $near 似乎被忽略了(在没有这个查询的情况下测试带来相同的结果)但是当我过滤到其他一些可以正常工作的内容(如 Name="test")时,限制也有效,但我不能跳过这个响应的某些地方......
我希望有人能理解我并帮助我 =)!
非常感谢!
【问题讨论】:
-
“我得到了位置,但它们是按数据库序列(原文如此)而不是按距离“排序”的” 研究得很好,实际上是我对阅读的怀疑。猜测一下,我会说这些是完全按照
Article模式中places 数组的ObjectId值的顺序表示的。这真的不适合你,我能想到的让它最有效地工作的方法是将“文章”列表存储在“地点”条目上,或者作为映射存储在单独的集合中.我可以在不更改数据的情况下完成,但这将是一个非常手动的过程。 -
嗯,是的,您是对的,实际订单是按 {ObjectId} 排序的,但是将文章存储在这些地方并没有帮助 - 因为很多地方 :( 找到正确的需要很长时间还是? - 我无法在已填充的文档中使用 near 进行查询?
-
这是预期的。
.populate()不会为此工作。因此,您可以在客户端“手动”执行查询(这基本上是 populate 正在做的事情),并根据需要将“有序”结果嫁给父母。 -
好吧,当我理解你的正确时,我只有不同的方法:1.)在找到的地方手动计算距离(我必须谷歌如何xD)2.)在地方制作 $geoNear 并搜索在每个地方寻找正确的文章(但是有很多地方,一个地方有很多文章=>查询需要很长时间)因为我绝对需要按距离排序的地方(所以 $lookup)没有帮助吗?
标签: node.js mongodb mongoose populate