如何使用mongoose在mongodb中使用纬度和经度查找附近的点

Posted

技术标签:

【中文标题】如何使用mongoose在mongodb中使用纬度和经度查找附近的点【英文标题】:How to find nearby points using latitude and longitude in mongo db using mongoose 【发布时间】:2020-08-29 23:01:27 【问题描述】:

架构:

const locationSchema = new mongoose.Schema(
    id:String,
    name:type: String , required:true,
    address:String,
    rating:type:Number , "default":0, min:0 , max:5 ,
    facilities:[String],
    // geoJSON schema 1
    coords: 
    
        type: type: String,
        coordinates:[]

    ,

    openingTimes: [openingTimeSchema],
    reviews: [reviewSchema]
    );

    locationSchema.index('coords':'2dsphere')

端点:http://localhost:3000/api/locations?lng=-0.7992599&lat=51.378091

const theEarth = (function() 
    console.log('theEarth');
    const earthRadius = 6371; // km, miles is 3959

    const getDistanceFromRads = function(rads) 
      return parseFloat(rads * earthRadius);
    ;

    const getRadsFromDistance = function(distance) 
      return parseFloat(distance / earthRadius);
    ;

    return 
      getDistanceFromRads: getDistanceFromRads,
      getRadsFromDistance: getRadsFromDistance
    ;
  )();

module.exports.locationsListByDistance = (req,res) => 

    const longitude = parseFloat(req.query.lng);
    const latitude = parseFloat(req.query.lat);
    //const maxDistance = parseFloat(req.query.maxDistance);
     Loc.aggregate(
        [
            $geoNear: 
                near:  type: "Point", coordinates: [ longitude , latitude ] ,
                distanceField: "coords.calculated", // required
                maxDistance: theEarth.getRadsFromDistance(20),
                includeLocs: "coords.location",
                spherical:true


              

            
        ],function(err,results)
            console.log(results);
        );




    sendJsonResponse(res,200,results);

;

错误:

UnhandledPromiseRejectionWarning: MongoError: There is more than one 2dsphere index on Loc8r.locations; unsure which to use for $geoNear
    at MessageStream.messageHandler (E:\Udemy\NodeTutorial\getting-mean\loc8r\node_modules\mongodb\lib\cmap\connection.js:261:20)      
    at MessageStream.emit (events.js:198:13)
    at processIncomingData (E:\Udemy\NodeTutorial\getting-mean\loc8r\node_modules\mongodb\lib\cmap\message_stream.js:144:12)
    at MessageStream._write (E:\Udemy\NodeTutorial\getting-mean\loc8r\node_modules\mongodb\lib\cmap\message_stream.js:42:5)
    at doWrite (_stream_writable.js:415:12)
    at writeOrBuffer (_stream_writable.js:399:5)
    at MessageStream.Writable.write (_stream_writable.js:299:11)
    at Socket.ondata (_stream_readable.js:709:20)
    at Socket.emit (events.js:198:13)
    at addChunk (_stream_readable.js:288:12)
    at readableAddChunk (_stream_readable.js:269:11)
    at Socket.Readable.push (_stream_readable.js:224:10)
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
(node:5040) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async 
function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
GET /bootstrap/bootstrap.min.css 304 0.954 ms - -
GET /stylesheets/style.css 304 5.782 ms - -
GET /api/bootstrap/jquery.min.js 404 65.965 ms - 3123
GET /api/bootstrap/bootstrap.min.js 404 116.055 ms - 3123

我正在使用上述方法来查找距离在端点中的查询参数中放置的经度和纬度附近但结果返回未定义的文档,请告诉如何更正此错误。

【问题讨论】:

【参考方案1】:
module.exports.locationsListByDistance = (req,res) => 

        const longitude = parseFloat(req.query.lng);
        const latitude = parseFloat(req.query.lat);
        //const maxDistance = parseFloat(req.query.maxDistance);
       // const options = near :[longitude,latitude],maxDistance:10000
        Loc.find(

          coords: 
            $near : 


              $maxDistance: 10,
              $geometry : 
                type : 'Point',
                coordinates:[longitude,latitude]
              
            
          
        ).find((error,results)=>
          if (error) console.log(error);
        //console.log(JSON.stringify(results, 0, 2));
        sendJsonResponse(res,200,results);
        );

       ;

这工作正常。

【讨论】:

【参考方案2】:

您基本上有多个 2dsphere 索引。您必须指定用于此查询的查询。尝试修改您的 geoNear 查询以包含正确的索引:

$geoNear: 
near:  type: "Point", coordinates: [longitude, latitude] ,
distanceField: "coords.calculated", // required
maxDistance: theEarth.getRadsFromDistance(20),
includeLocs: "coords.location",
spherical: true,
key: 'indexName'

【讨论】:

以上是关于如何使用mongoose在mongodb中使用纬度和经度查找附近的点的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Mongoose 在 MongoDB 中插入 JSON 数组

如何在 typescript 中使用 mongoose 在 mongodb 中插入数据?

如何使用 Mongoose 在 mongoDB 中填充 3 个集合

如何在 mongoose/mongodb 查询子文档中使用 mapreduce?

如何在 mongoose/mongodb 查询子文档中使用 mapreduce?

如何使用 Mongoose 在 mongodb 中存储动态对象数组?