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

时间:2017-03-04 13:03:57

标签: mysql node.js sequelize.js

我在我的mysql数据库中存储了一个POINT类型的位置:

sunday

看起来这个点正确存储: enter image description here

我正在尝试使用mysql本地module.exports = function (sequelize, DataTypes) { var Promotion = sequelize.define('promotion', { userId: { type: DataTypes.STRING, allowNull: false }, location: { type: DataTypes.GEOMETRY('POINT'), allowNull: false } 函数查找一组边界内的所有行。我在postgresql中使用它并且它工作得很好,但是当我切换到mysql时它开始抛出错误:

ST_MakeEnvelope

错误:

  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. 函数和sequelize进行查询?

修改

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

ST_MakeEnvelope

1 个答案:

答案 0 :(得分:1)

我不熟悉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函数示例中所示(它需要两个参数,因此可能是您第一次出错的原因Incorrect parameter count in the call to native function 'ST_MakeEnvelope')。而且,正如我在开始时所说,我绝对不是这方面的专家,只是在看了MySQL文档之后的建议。

修改

以下是Sequelize文档中$overlap的说明

  

$ overlap:[1,2] //&& [1,2](PG阵列重叠算子)

我认为你应该以不同的方式构建你的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;

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