如何在 Sequelize Postgres 中使用 Lowercase 函数
How to use Lowercase function in Sequelize Postgres
我正在尝试使用小写函数在 Sequelize 中进行字符串搜索。
我设法使用 ilike 来做到这一点。
我的问题是在这种情况下如何使用小写函数?
使用ilike的findAll
如下:
Db.models.Person.findAll(where: {firstName: {$ilike: `somename`}});
如何更改为lower(firstname) = lower('somename');
您可以在 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');
PostgreSQL 通常使用 case-sensitive 归类。这意味着每列中显示的数据都会与您的查询逐字比较。
您有多种选择:
1.按照 Ben 的回答,将包装列和数据库包装在 sequelize.fn('lower')
调用中。
优点:没有数据库更改。
缺点:您需要记住在每个查询中使用它。放弃索引(除非您已经创建了 functional index)并按顺序扫描 tables,导致 look-ups 变慢且 tables 变大。相当冗长的代码。
2。使用 ILIKE,case-insensitively 匹配模式
准确查找姓名:
Db.models.Person.findAll(where: {firstName: {$iLike: 'name'}});
要查找可能包含在任意字符中的片段:
Db.models.Person.findAll(where: {firstName: {$iLike: '%name%'}});
优点:容易记住。没有 Sequelize 函数包装器——它是一个 built-in 运算符,所以语法更简洁。无需特殊索引或数据库更改。
缺点:速度慢,除非你开始搞乱像 pg_trgm
这样的扩展
3。使用 citext 类型定义文本列,该类型隐式比较小写
将您的列类型定义为 'citext'(而不是 text
或 character varying
)具有与以下相同的实际效果:
select * from people where name = 'DAVID'
对此...
select * from people where LOWER(name) = LOWER('DAVID')
PostgreSQL 文档将其显示为如何使用 citext 类型创建 table 的示例:
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 基本上将 "text" 列换成 "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
}
});
那么您对该列的搜索将总是 case-insensitive 与常规 where =
查询
优点:无需将查询包装在丑陋的 sequelize.fn
调用中。无需记住明确小写。区域设置感知,因此适用于所有字符集。
缺点:您需要记住在第一次定义 table 时在 Sequelize 定义中使用它。始终激活 - 您需要知道在定义 tables.
时要进行不区分大小写的搜索
我正在尝试使用小写函数在 Sequelize 中进行字符串搜索。 我设法使用 ilike 来做到这一点。 我的问题是在这种情况下如何使用小写函数?
使用ilike的findAll
如下:
Db.models.Person.findAll(where: {firstName: {$ilike: `somename`}});
如何更改为lower(firstname) = lower('somename');
您可以在 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');
PostgreSQL 通常使用 case-sensitive 归类。这意味着每列中显示的数据都会与您的查询逐字比较。
您有多种选择:
1.按照 Ben 的回答,将包装列和数据库包装在 sequelize.fn('lower')
调用中。
优点:没有数据库更改。
缺点:您需要记住在每个查询中使用它。放弃索引(除非您已经创建了 functional index)并按顺序扫描 tables,导致 look-ups 变慢且 tables 变大。相当冗长的代码。
2。使用 ILIKE,case-insensitively 匹配模式
准确查找姓名:
Db.models.Person.findAll(where: {firstName: {$iLike: 'name'}});
要查找可能包含在任意字符中的片段:
Db.models.Person.findAll(where: {firstName: {$iLike: '%name%'}});
优点:容易记住。没有 Sequelize 函数包装器——它是一个 built-in 运算符,所以语法更简洁。无需特殊索引或数据库更改。
缺点:速度慢,除非你开始搞乱像 pg_trgm
这样的扩展3。使用 citext 类型定义文本列,该类型隐式比较小写
将您的列类型定义为 'citext'(而不是 text
或 character varying
)具有与以下相同的实际效果:
select * from people where name = 'DAVID'
对此...
select * from people where LOWER(name) = LOWER('DAVID')
PostgreSQL 文档将其显示为如何使用 citext 类型创建 table 的示例:
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 基本上将 "text" 列换成 "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
}
});
那么您对该列的搜索将总是 case-insensitive 与常规 where =
查询
优点:无需将查询包装在丑陋的 sequelize.fn
调用中。无需记住明确小写。区域设置感知,因此适用于所有字符集。
缺点:您需要记住在第一次定义 table 时在 Sequelize 定义中使用它。始终激活 - 您需要知道在定义 tables.
时要进行不区分大小写的搜索