Giter Club home page Giter Club logo

Comments (8)

benmarten avatar benmarten commented on June 3, 2024 1

As promised, here it is. Brings down the response time from 8s to 1s.

Person.nearby = function(here, max, next) {

max = Number(max || 10);

var geo = here.split(/,\s*/);
var lat = geo[1];
var lng = geo[0];

var table = 'person';
var column = 'location';

var sql = 'SELECT x.id from ( \
            SELECT id, ( \
                  6373 * acos ( \
                  cos ( radians( ' + lat + ' ) ) \
                  * cos( radians( X(' + column + ') ) ) \
                  * cos( radians( Y(' + column + ') ) - radians( ' + lng + ' ) ) \
                  + sin ( radians( ' + lat + ' ) ) \
                  * sin( radians( X(' + column + ') ) ) \
                ) \
            ) AS distance \
          FROM ' + table + ' \
              ORDER BY distance \
              ) x \
          WHERE x.distance < ' + max + ';';

Person.app.datasources.mysql.connector.query(sql, function(err, result) {
  if (err) {
    console.log('Error retrieving persons nearby ...');
    console.log(err);
    return next(err);
  }

  var ids = [];
  for (var i = 0; i < result.length; i++) {
    ids.push(result[i].id);
  };

  Person.find({
    'where': {
      'id': {
        'inq': ids
      }
    }
  }, function(err, res) {
    next(err, res);
  });
});

}

If you want to do it in miles, replace the constant 6373 with 3959.
The sql query idea came from here: http://stackoverflow.com/questions/21168380/use-mysql-spatial-extensions-to-select-points-inside-circle

There is also a native distance mysql function 'st_distance', but as mentioned on stack overflow it is not good for km... so i ended up with the above query, based on the haversine distance.

from loopback-connector-mysql.

benmarten avatar benmarten commented on June 3, 2024 1
  "location": {
    "type": "geopoint",
    "required": true
  },

from loopback-connector-mysql.

benmarten avatar benmarten commented on June 3, 2024

Ok, so I am pretty sure, that the calculation is done in node... since its blocking and taking so long (with that amount of data).

I will use a custom SQL query to retrieve the users based on my needs, similar to this one:

SET @lat = 49;
SET @lon = 8;
SET @RaD = 0.1;

SELECT
X(location),Y(location), (
6373 * acos (
cos ( radians( @lat ) )
* cos( radians( X(location) ) )
* cos( radians( Y(location) ) - radians( @lon ) )
+ sin ( radians( @lat ) )
* sin( radians( X(location) ) )
)
) AS distance
FROM person
HAVING distance < @RaD

I hope that will help someone...

from loopback-connector-mysql.

raymondfeng avatar raymondfeng commented on June 3, 2024

If MySQL has native geo query, we can try to support it by mapping nearby to a sql function.

from loopback-connector-mysql.

loay avatar loay commented on June 3, 2024

Hi @benmarten
Is this still an issue?

from loopback-connector-mysql.

benmarten avatar benmarten commented on June 3, 2024

We are using above workaround in production, I have no idea if the implementation has been changed in the original approach...

from loopback-connector-mysql.

juancaacuna avatar juancaacuna commented on June 3, 2024

Hi @benmarten ! What DataType are you using on SQL for the location column?
I like your approach!

Thanks!

from loopback-connector-mysql.

alterx avatar alterx commented on June 3, 2024

Hey, guys, for the sake of completeness, as of MySQL 5.7.6. you can use the ST_Distance_Sphere function which achieves the same result:

  Event.nearby = function([lat, lng], distance = 5, {limit = 10, skip = 0} = {}, cb) {
    const userLocation = new GeoPoint({
      lat,
      lng,
    });

    const sql = `SELECT * from
      (SELECT *, (ST_Distance_Sphere(ST_GeomFromText('POINT(${lng} ${lat})'), location, 6373))
      AS distance FROM mydb.Event) x WHERE x.distance <= ${distance} ORDER BY distance LIMIT ${limit} OFFSET ${skip};`;

    const ds = Event.app.dataSources.db;
    const mySQLPool = ds.connector.client;
    mySQLPool.query(sql,
    function(err, rows, fields) {
      if (err) return cb(err);

      return cb(null, rows);
    });
  };

from loopback-connector-mysql.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.