Sequelize WHERE sequelize.fn(...)AND something =' something'订购问题

时间:2017-04-07 09:20:33

标签: node.js sequelize.js postgis

我有一个Sequelize findOne函数,它可以选择给定点与多边形相交的行(col' geom')AND status =' active'。

var point = sequelize.fn('ST_GeomFromText', 'POINT(' + lng + ' ' + lat +')', 4326);
var intersects = sequelize.fn('ST_Intersects', sequelize.col('geom'), point);

GeoCounty.findOne({
  attributes: ['id', 'name' ],
  where: {
    status: 'active',
    $and: intersects
  },
  plain: true
})

截至目前,它运作得很好。它生成的SQL看起来像:

SELECT "id", "name" FROM "geocounty" AS "geocounty" WHERE "geocounty"."status" = 'active' AND (ST_Intersects("geom", ST_GeomFromText('POINT(-98.025006 43.714735)', 4326))) LIMIT 1;

我真正想要的是:

SELECT "id", "name" FROM "geocounty" AS "geocounty" WHERE (ST_Intersects("geom", ST_GeomFromText('POINT(-98.025006 43.714735)', 4326))) AND "geocounty"."status" = 'active' LIMIT 1;    

也就是说ST_Intersects子句首先出现,AND status =' active'紧接着。

我的问题是:
    1.执行查询的第一种方式是否有任何性能损失?     2.有没有办法在Sequelize中构建这样的where子句?

这不起作用:

GeoCounty.findOne({
  attributes: ['id', 'name' ],
  where: {
    intersects,
    $and: {
      status: 'active'
    }
  },
  plain: true
})    

它产生这个SQL:

SELECT "id", "name" FROM "geocounty" AS "geocounty" WHERE "geocounty"."intersects" = ST_Intersects("geom", ST_GeomFromText('POINT(-98.025006 43.714735)', 4326)) AND ("geocounty"."status" = 'active') LIMIT 1;    

没有geocounty.intersects ......

1 个答案:

答案 0 :(得分:4)

我在寻找类似问题时偶然发现了这篇文章,并为我找到了解决方案,这可能对您有帮助。

我将函数调用包装到了其他地方。我的代码如下(在NodeJs 10.9.0,MariaDB上的Sequelize 4.38.0中工作):

Cat.findOne({
  where: {
    color: 'red',
    $and: sequelize.where(sequelize.fn('char_length', sequelize.col('cat_name')), 5)
  }
});
SELECT id, cat_name, color FROM cat_table WHERE color = 'red' AND char_length(cat_name) = 5;

在您的示例中,它看起来像这样(未经测试):

var intersects = sequelize.fn('ST_Intersects', sequelize.col('geom'), point);
GeoCounty.findOne({
  attributes: ['id', 'name' ],
  where: {
    $and: sequelize.where(intersects, 1),
    status: 'active'
  },
  plain: true
})