猫鼬近距离搜索-如何在给定距离内排序?

问题描述 投票:0回答:3

我正在使用猫鼬和带有maxDistance的near查询来过滤靠近给定gps位置的元素。但是,near查询会覆盖其他排序。我想要的是找到给定点的maxDistance内的所有元素,然后按其他属性排序。这是我目前正在做的一个例子:

模式:

mongoose.Schema({
    name: {
        type: String,
        required: true
    },
    score: {
        type: Number,
        required: true,
        default: 0
    },
    location: {
        type: {
            type: String,
            default: 'Point',
        },
        coordinates: {
            type: [Number]
        }
    },
    ....
});

查询:

model.find({
  "location.coordinates": {
    "$near": {
      "$maxDistance": 1000,
      "$geometry": {
        "type": "Point",
        "coordinates": [
          10,
          10
        ]
      }
    }
  }
}).sort('-score');

在查找后添加.sort在这里无济于事,并且无论如何都会以接近的顺序返回项目。

mongodb mongoose geojson
3个回答
0
投票

您是否尝试过使用汇总?我知道常规查询有局限性。

model.aggregate([
   {$geoNear: {
      near: { type: "Point", coordinates: [ 10 , 10 ] },
      distanceField: "distCalculated",
      maxDistance: 1000
   }},
   {$sort:{score:-1}}
])

0
投票

$near按距离对文档进行排序,这很浪费。最好使用不对文档进行排序的$geoWithin。类似于:

model.find({
  "location.coordinates": { 
     $geoWithin: { $center: [ [-74, 40.74], <radius> ] } } }
).sort({score: -1});

$center文档具有更多详细信息。


0
投票

正确的语法类似于$ near:

$center

要使$ near工作,您需要在相关集合上使用2dsphere索引:

router.get("/test", async (req, res) => {
  const lat = 59.9165591;
  const lng = 10.7881978;
  const maxDistanceInMeters = 2000;

  const result = await model
    .find({
      location: {
        $near: {
          $geometry: {
            type: "Point",
            coordinates: [lng, lat],
          },
          $maxDistance: maxDistanceInMeters,
        },
      },
    })
    .sort("-score");

  res.send(result);
});

在mongodb db.collection.createIndex( { "location" : "2dsphere" } ) 文档中它说:

$ near按距离对文档进行排序。如果您还包括一个sort()查询sort()有效地对匹配文档进行重新排序覆盖$ near已经执行的排序操作。使用时使用地理空间查询进行sort(),请考虑使用$ geoWithin运算符,不会对文档排序,而不是$ near。

由于您对按距离排序不感兴趣,因为Nic不需要使用$ near,所以最好像这样使用$near

$geoWithin

为了计算半径,我们按照router.get("/test", async (req, res) => { const lat = 59.9165591; const lng = 10.7881978; const distanceInKilometer = 2; const radius = distanceInKilometer / 6378.1; const result = await model .find({ location: { $geoWithin: { $centerSphere: [[lng, lat], radius] } }, }) .sort("-score"); res.send(result); }); 将公里除以6378.1,将英里除以3963.2。

因此代码将找到半径2公里内的位置。

© www.soinside.com 2019 - 2024. All rights reserved.