spy*_*t01 12 postgresql node.js sequelize.js
我试图使用小写函数在Sequelize中进行字符串搜索.我设法使用ilike做到这一点.我的问题是如何在这种情况下使用小写函数?
在findAll使用ILIKE是如下:
Db.models.Person.findAll(where: {firstName: {$ilike: `somename`}});
Run Code Online (Sandbox Code Playgroud)
如何将其更改为 lower(firstname) = lower('somename');
Lee*_*son 25
PostgreSQL通常使用区分大小写的排序规则.这意味着每列中显示的数据将根据您的查询进行字面比较.
你有几个选择:
1.按照Ben的回答,将你的包裹列和数据库包装在一个sequelize.fn('lower')电话中.
优点:没有数据库更改.
缺点:您需要记住每次查询都使用它.Foregoes索引(除非您已经创建了功能索引)并按顺序扫描表,导致大表的查找速度变慢.相当冗长的代码.
2.使用ILIKE,以区分大小写匹配模式
要准确找到名称:
Db.models.Person.findAll(where: {firstName: {$iLike: 'name'}});
要查找可包含在任意字符中的片段:
Db.models.Person.findAll(where: {firstName: {$iLike: '%name%'}});
优点:易于记忆.No Sequelize函数包装器 - 它是一个内置的运算符,因此语法更整洁.无需特殊索引或数据库更改.
3.使用citext类型定义文本列,隐式比较小写
将列类型定义为"citext"(而不是text或character varying)与实现此目的具有相同的实际效果:
select * from people where name = 'DAVID'
对...
select * from people where LOWER(name) = LOWER('DAVID')
PostgreSQL文档将此作为如何使用citext类型创建表的示例:
CREATE TABLE users (
nick CITEXT PRIMARY KEY,
pass TEXT NOT NULL
);
INSERT INTO users VALUES ( 'larry', md5(random()::text) );
INSERT INTO users VALUES ( 'Tom', md5(random()::text) );
INSERT INTO users VALUES ( 'Damian', md5(random()::text) );
INSERT INTO users VALUES ( 'NEAL', md5(random()::text) );
INSERT INTO users VALUES ( 'Bjørn', md5(random()::text) );
SELECT * FROM users WHERE nick = 'Larry';
Run Code Online (Sandbox Code Playgroud)
TL; DR基本上换掉"citext"的"文本"列.
citext模块与PostgreSQL 8.4捆绑在一起,因此无需安装任何扩展.但您确实需要在使用以下SQL的每个数据库上启用它:
CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public;
然后在Sequelize定义中,定义一个type属性:
// Assuming `Conn` is a new Sequelize instance
const Person = Conn.define('person', {
firstName: {
allowNull: false,
type: 'citext' // <-- this is the only change
}
});
Run Code Online (Sandbox Code Playgroud)
然后,对该列的搜索将始终对常规where =查询不区分大小写
优点:无需将您的查询包装在丑陋的sequelize.fn调用中.无需记住显式小写.可识别区域设置,因此适用于所有字符集.
缺点:首次定义表时,您需要记住在Sequelize定义中使用它.始终激活 - 您需要知道在定义表时您需要进行不区分大小写的搜索.
小智 7
您可以在where子句中使用本机函数:
Db.models.Person.findAll({
where: sequelize.where(
sequelize.fn('lower', sequelize.col('firstname')),
sequelize.fn('lower', 'somename')
)
});
Run Code Online (Sandbox Code Playgroud)
这将转化为
select * from person where lower(firstname) = lower('somename');
Run Code Online (Sandbox Code Playgroud)