具有sequelize和节点js的Mysql本机空间函数

我在我的mysql数据库中存储一个POINTtypes的位置:

module.exports = function (sequelize, DataTypes) { var Promotion = sequelize.define('promotion', { userId: { type: DataTypes.STRING, allowNull: false }, location: { type: DataTypes.GEOMETRY('POINT'), allowNull: false } 

它看起来像点被正确存储: 在这里输入图像说明

我试图使用mysql本机ST_MakeEnvelope函数查找一组边界内的所有行。 我用这个postgresql和它完美的工作,但是当我切换到MySQL它开始抛出错误:

  if (northEastLng && northEastLat && southWestLat && southWestLng) { where.location = { $overlap: db.sequelize.fn('ST_MakeEnvelope', southWestLng, southWestLat, northEastLng, northEastLat) } } promotion.findAll({ where, }) .then(promoters => { res.json(promoters) }) .catch(err => { console.log('ERROR: ', err) }) 

错误:

 Error: ER_WRONG_PARAMCOUNT_TO_NATIVE_FCT: Incorrect parameter count in the call to native function 'ST_MakeEnvelope' 

所以我尝试了两点:

 const POINT_ONE = `POINT(${southWestLng} ${southWestLat})` const POINT_TWO = `POINT(${northEastLng} ${northEastLat})` where.location = { $overlap: db.sequelize.fn('ST_MakeEnvelope', POINT_ONE, POINT_TWO) } 

现在我得到这个错误:

 SequelizeDatabaseError: UNKNOWN_CODE_PLEASE_REPORT: Geometry byte string must be little endian. 

一直在四处寻找,而不太确定从哪里去。 如何使用ST_MakeEnvelope函数和sequelize进行查询?

编辑

从piotrbienias响应中添加生成的sql:

 SELECT `promotion`.`id`, `promotion`.`userId`, `promotion`.`title`, `promotion`.`description`, `promotion`.`startDate`, `promotion`.`endDate`, `promotion`.`isIndefinite`, `promotion`.`isApproved`, `promotion`.`status`, `promotion`.`reach`, `promotion`.`trustRanking`, `promotion`.`isLocationBased`, `promotion`.`address`, `promotion`.`city`, `promotion`.`state`, `promotion`.`zip`, `promotion`.`location`, `promotion`.`createdAt`, `promotion`.`updatedAt`, `promotion`.`categoryId `, `promotionImages`.`id` AS `promotionImages.id`, `promotionImages`.`url` AS `promotionImages.url`, `promotionImages`.`publicId` AS `promotionImages.publicId`, `promotionImages`.`secureUrl` AS `promotionImages.secureUrl`, `promotionImages`.`isApproved` AS `promotionImages.isApproved`, `promotionImages`.`createdAt` AS `promotionImages.createdAt`, `promotionImages`.`updatedAt` AS `promotionImages.updatedAt`, `promotionImages`.`promotionId` AS `promotionImages.promotionId`, `category`.`id` AS `cat egory.id`, `category`.`title` AS `category.title` FROM `promotions` AS `promotion` LEFT OUTER JOIN `promotionImages` AS `promotionImages` ON `promotion`.`id` = `promotionImages`.`promotionId` LEFT OUTER JOIN `categories` AS `category` ON `promotion`.`categoryId` = `category`.`id` WHERE `promotion`.`location` && ST_MakeEnvelope(ST_GeomFromText('POINT(-80.30252222253421 25.802030960352745)'), ST_GeomFromText('POINT(-80.30252222253421 25.802030960352745)')); 

我不熟悉MySQL的Geometry部分,但不应该在使用它们之前在这些点上使用ST_GeomFromText函数?

 where.location = { $overlap: db.sequelize.fn( 'ST_MakeEnvelope', db.sequelize.fn('ST_GeomFromText', POINT_ONE), db.sequelize.fn('ST_GeomFromText', POINT_TWO), ) } }; 

就像它在ST_MakeEnvelope函数的例子中所表示的ST_MakeEnvelope (并且它需要两个参数,所以这可能是您的第一个错误的原因Incorrect parameter count in the call to native function 'ST_MakeEnvelope' )。 而且,正如我一开始所说的,我绝对不是这方面的专家,只是看了一下MySQL文档后的build议。

编辑

以下是来自Sequelize文档的$overlap描述

$ overlap:[1,2] // && [1,2](PG数组重叠操作符)

我认为你应该build立你的Sequelize查询不同,没有$overlap 。 我想你应该使用ST_Contains函数,你的where对象应该如下

 { where: db.sequelize.where( db.sequelize.fn( 'ST_Contains', db.sequelize.fn( 'ST_MakeEnvelope', db.sequelize.fn('ST_GeomFromText', POINT_ONE), db.sequelize.fn('ST_GeomFromText', POINT_TWO) ), db.sequelize.col('promotion.location') ), '=', 1 ) } 

在我看来,你想要的SQL应该是这样的:

 WHERE ST_Contains(POLYGON(...), location) 

上面的Sequelize查询会生成

 WHERE ST_Contains(ST_MakeEnvelope(ST_GeomFromText(POINT_ONE), ST_GeomFromText(POINT_TWO)), location) = 1; 

应该检查从两点创build的多边形是否包含location列的值。 ST_Contains返回1或0,所以我认为在这种情况下= 1条件应该是可以的。