【问题标题】:mongoose $near populate ignoredmongoose $near populate 被忽略
【发布时间】: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 正在做的事情),并根据需要将“有序”结果嫁给父母。
  • 或者你可以在服务器上使用$lookup。但当然问题是所需的聚合$geoNear 需要直接在您的“地点”集合上运行,而$lookup 需要数据与“文章”相关联。当前,该服务器操作的引用位于错误的集合中。这些基本上是您需要做出的决定。
  • 好吧,当我理解你的正确时,我只有不同的方法:1.)在找到的地方手动计算距离(我必须谷歌如何xD)2.)在地方制作 $geoNear 并搜索在每个地方寻找正确的文章(但是有很多地方,一个地方有很多文章=>查询需要很长时间)因为我绝对需要按距离排序的地方(所以 $lookup)没有帮助吗?

标签: node.js mongodb mongoose populate


【解决方案1】:

所以我有一个解决我的问题的方法......

https://docs.mongodb.com/manual/reference/command/geoNear/

使用 db.aggregate 代替 db.find!

在那里你可以定义一个单独的查询 =)

【讨论】:

    猜你喜欢
    • 2012-07-06
    • 2018-09-10
    • 1970-01-01
    • 2023-03-30
    • 2018-07-06
    • 2016-02-14
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多