Sequelize geospatial query: find “n” closest points to a location

后端 未结 3 649
旧时难觅i
旧时难觅i 2020-12-16 18:13

Using Sequelize and geospatial queries, if I want to find the \"n\" closest points to a certain location, how should the Sequelize query be?

Assume I have a model th

3条回答
  •  遥遥无期
    2020-12-16 18:33

    When you surround sequelize.fn with brackets, you must also include a string as an alias:

    [sequelize.fn('ST_Distance_Sphere', sequelize.literal('geolocation'), location), 'ALIASNAME']
    

    Also, try changing ST_Distance to ST_Distance_Sphere. So:

        const location = sequelize.literal(`ST_GeomFromText('POINT(${lng} ${lat})', 4326)`);
    
        User.findAll({
          attributes: [[sequelize.fn('ST_Distance_Sphere', sequelize.literal('geolocation'), location),'distance']],
          order: 'distance',
          limit: 10,
          logging: console.log
        })
        .then(function(instance){
          console.log(instance);
        })
    

    This is actually working for me. obs: be sure you substitute 'User' with the model in which you have the geometry data type.

    Update: If you still can't order using order: 'distance', maybe you should declare it in a var and use order: distance without quotes, like this:

        var lat = parseFloat(json.lat);
        var lng = parseFloat(json.lng);
        var attributes = Object.keys(User.attributes);
    
        var location = sequelize.literal(`ST_GeomFromText('POINT(${lng} ${lat})')`);
        var distance = sequelize.fn('ST_Distance_Sphere', sequelize.literal('geolocation'), location);
        attributes.push([distance,'distance']);
    
        var query = {
          attributes: attributes,
          order: distance,
          include: {model: Address, as: 'address'},
          where: sequelize.where(distance, {$lte: maxDistance}),
          logging: console.log
        }
    

    Update on distance accuracy:

    The solution mentioned by sarikaya does seem to be more accurate. Here is how to do it using postgres:

    var distance = sequelize.literal("6371 * acos(cos(radians("+lat+")) * cos(radians(ST_X(location))) * cos(radians("+lng+") - radians(ST_Y(location))) + sin(radians("+lat+")) * sin(radians(ST_X(location))))");
    

提交回复
热议问题