Cha*_*ase 6 postgis node.js sequelize.js
我有一个 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
})
Run Code Online (Sandbox Code Playgroud)
截至目前,它工作得很好。它生成的 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;
Run Code Online (Sandbox Code Playgroud)
我真正想要的是:
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;
Run Code Online (Sandbox Code Playgroud)
也就是说 ST_Intersects 子句在前,AND status='active' 在后。
我的问题是:
1. 以第一种有效的方式执行查询是否有任何性能损失?2. 有没有办法在 Sequelize 中构造像这样的 where 子句?
这不起作用:
GeoCounty.findOne({
attributes: ['id', 'name' ],
where: {
intersects,
$and: {
status: 'active'
}
},
plain: true
})
Run Code Online (Sandbox Code Playgroud)
它产生这个 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;
Run Code Online (Sandbox Code Playgroud)
没有 geocounty.intersects...
小智 10
我在搜索类似问题时偶然发现了这篇文章,并为我找到了一个解决方案,这可能会帮助您解决 #2。
我将函数调用包装到一个额外的地方。我的代码看起来像这样(在 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;
Run Code Online (Sandbox Code Playgroud)
在您的示例中,它看起来像这样(未测试):
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
})
Run Code Online (Sandbox Code Playgroud)