2017-05-16 35 views
5

Sequelize और भू-स्थानिक प्रश्नों का उपयोग करते हुए, "मैं" किसी निश्चित स्थान पर निकटतम बिंदु ढूंढना चाहता हूं, तो सीक्वेलिज़ क्वेरी कैसे होनी चाहिए?भू-स्थानिक क्वेरी को सीक्वेलिज़ करें:

मान लें मैं एक मॉडल है कि कुछ इस तरह दिखता है:

sequelize.define('Point', {geo: DataTypes.GEOMETRY('POINT')}); 

अब हम की तरह कुछ के माध्यम से DB में इनपुट 100 यादृच्छिक अंक मान लीजिए:

db.Point.create({geo: {type: 'Point', coordinates: [randomLat, randomLng]}}); 

कल्पना कीजिए हमारे पास एक lat और lng किसी स्थान को परिभाषित करने के लिए चर, और हम इसे 10 निकटतम बिंदु ढूंढना चाहते हैं। जब मैं इस क्वेरी को चलाता हूं तो मुझे एक त्रुटि मिलती है:

const location = sequelize.literal(`ST_GeomFromText('POINT(${lat} ${lng})', 4326)`); 

db.Point.findAll({ 
    attributes: [['distance', sequelize.fn('ST_Distance', sequelize.col('Point'), location)]], 
    order: 'distance', 
    limit: 10 
}); 

// -> TypeError: s.replace is not a function 

कोई विचार यह समस्या/इसे ठीक करने का तरीका क्या है?

Thx!

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

इसके अलावा, ST_Distance_Sphere को ST_Distance बदलने का प्रयास करें:

+0

मुझे यकीन नहीं है, लेकिन ऐसा लगता है कि आपके पास –

+0

विशेषताएँ के आसपास अतिरिक्त वर्ग ब्रैकेट हैं? –

उत्तर

1

जब आप चारों ओर ब्रैकेट के साथ sequelize.fn, आप भी उपनाम के रूप में एक स्ट्रिंग शामिल करना चाहिए। तो:

const location = sequelize.literal(`ST_GeomFromText('POINT(${lat} ${lng})', 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); 
    }) 

यह वास्तव में मेरे लिए काम कर रहा है। obs: सुनिश्चित करें कि आप उस मॉडल के साथ 'उपयोगकर्ता' को प्रतिस्थापित करते हैं जिसमें आपके पास ज्यामिति डेटा प्रकार है।

अद्यतन: आप अभी भी order: 'distance' का उपयोग कर आदेश नहीं कर सकते हैं, हो सकता है आप यह एक वर में, घोषित करने और इस तरह बिना उद्धरण चिह्नों के order: distance उपयोग करना चाहिए:

var lat = parseFloat(json.lat); 
    var lng = parseFloat(json.lng); 
    var attributes = Object.keys(User.attributes); 

    var location = sequelize.literal(`ST_GeomFromText('POINT(${lat} ${lng})')`); 
    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 
    } 
+0

यह क्वेरी मुझे निम्न त्रुटि देता है: 'त्रुटि: ऑर्डर एक सरणीकरण विधि के सरणी या उदाहरण का होना चाहिए।' मैंने 'ऑर्डर' को 'दूरी' के बजाय '[' दूरी '] में बदलने की कोशिश की और ' अब मुझे मिलता है: 'SequelizeDatabaseError: कॉलम User.distance मौजूद नहीं है'। – Pensierinmusica

+0

क्या आपने गुणों में स्ट्रिंग 'दूरी' शामिल की है? उद्धरण के बिना दूरी भी काम करना चाहिए: ... 'आदेश: दूरी' ... – Edudjr

0

बंद बिल्डिंग @ Edudjr के जवाब है,

const location = sequelize.literal(`ST_GeomFromText('POINT(${ startLongitude } ${ startLatitude })')`) 
const distance = sequelize.fn('ST_Distance_Sphere', sequelize.col('location'), location) 

const inRadius = await Position.findAll({ 
    order: distance, 
    where: sequelize.where(distance, { $lte: radius }), 
    logging: console.log 
}) 

जहां स्थिति के रूप में परिभाषित किया गया है: यह है कि क्या मैं इसे अपने परियोजना में काम करने के लिए प्राप्त करने के लिए किया था

sequelize.define('Position', { 
    location: DataTypes.GEOMETRY('POINT') 
}) 

Note that Point requires the coordinates in the format of (longitude latitude)

https://gis.stackexchange.com/questions/209008/incorrect-arguments-to-st-distance-sphere-in-special-cases

https://dba.stackexchange.com/questions/33410/whats-the-difference-between-pointx-y-and-geomfromtextpointx-y

0

MySQL एक त्रुटि है कि ढंग से काम ST_Distance_Sphere मौजूद नहीं है दे सकते हैं। उस स्थिति में आप इस वैकल्पिक समाधान का उपयोग कर सकते हैं:

मैं अक्षांश और देशांतर दशमलव के रूप में अलग-अलग बिंदु जानकारी रखता हूं।मान लें कि आप एक मॉडल है कि कुछ इस तरह दिखता होना चाहिए:

sequelize.define('Point', {latitude: DataTypes.DECIMAL(11,2)}, 
          {longitude: DataTypes.DECIMAL(11,2)}); 

कल्पना कीजिए कि हम एक स्थान को परिभाषित करने के लिए एक lat और lng चर है, और हम यह करने के लिए 10 निकटतम अंक लगाना चाहते हैं:

db.Point.findAll({ 
    attributes: [[sequelize.fn('POW',sequelize.fn('ABS',sequelize.literal("latitude-"+lat)),2),'x1'], 
       [sequelize.fn('POW',sequelize.fn('ABS',sequelize.literal("longitude-"+lng)),2),'x2']], 
    order: sequelize.fn('SQRT', sequelize.literal('x1+x2')), 
    limit: 10 
}); 

अद्यतन:

Haversine Formula साथ

, दूरी अधिक सटीक है:

db.Point.findAll({ 
    attributes: [[sequelize.literal("6371 * acos(cos(radians("+lat+")) * cos(radians(latitude)) * cos(radians("+lng+") - radians(longitude)) + sin(radians("+lat+")) * sin(radians(latitude)))"),'distance']], 
    order: sequelize.col('distance'), 
    limit: 10 
}); 
संबंधित मुद्दे