我正在尝试使用小写函数在Sequelize中进行字符串搜索。 我设法使用ilike做到这一点。 我的问题是如何在这种情况下使用小写函数?
使用ilike的findAll
如下:
Db.models.Person.findAll(where: {firstName: {$ilike: `somename`}});
如何将其更改为lower(firstname) = lower('somename');
答案 0 :(得分:22)
PostgreSQL通常使用区分大小写的排序规则。这意味着每列中显示的数据将根据您的查询进行字面比较。
您有几种选择:
<强> 1。按照Ben的回答,将您的包裹列和数据库打包在sequelize.fn('lower')
电话中。
优点:没有数据库更改。
缺点:您需要记住每次查询都使用它。 Foregoes索引(除非您已经创建了functional index)并按顺序扫描表,导致使用大表的查找速度变慢。相当冗长的代码。
<强> 2。使用ILIKE,不区分大小写匹配模式
要准确找到名称:
Db.models.Person.findAll(where: {firstName: {$iLike: 'name'}});
查找可能包含在任意字符中的片段:
Db.models.Person.findAll(where: {firstName: {$iLike: '%name%'}});
优点:易于记忆。 No Sequelize函数包装器 - 它是一个内置的运算符,所以语法更整洁。无需特殊索引或数据库更改。
缺点:慢,除非你开始搞乱像pg_trgm
这样的扩展第3。使用citext类型定义文本列,隐式比较小写
将列类型定义为&#39; citext&#39; (而不是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';
TL; DR基本上换掉你的&#34;文本&#34; &#34; citext&#34;。
的列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
}
});
然后,针对该列的搜索总是对常规where =
查询不区分大小写
优点:无需将您的查询包装在丑陋的sequelize.fn
调用中。无需记住显式小写。可识别区域设置,因此适用于所有字符集。
缺点:首次定义表时,您需要记住在Sequelize定义中使用它。始终激活 - 您需要知道在定义表时您将要进行不区分大小写的搜索。
答案 1 :(得分:6)
您可以在where子句中使用本机函数:
Db.models.Person.findAll({
where: sequelize.where(
sequelize.fn('lower', sequelize.col('firstname')),
sequelize.fn('lower', 'somename')
)
});
将转换为
select * from person where lower(firstname) = lower('somename');