我正嘗試使用小寫字母函數在Sequelize中進行字符串搜索。 我設法使用ilike。 我的問題是如何在這種情況下使用小寫函數?使用ILIKE如何在Sequelize中使用小寫字母函數Postgres
的findAll
是如下:
Db.models.Person.findAll(where: {firstName: {$ilike: `somename`}});
如何將其更改爲lower(firstname) = lower('somename');
我正嘗試使用小寫字母函數在Sequelize中進行字符串搜索。 我設法使用ilike。 我的問題是如何在這種情況下使用小寫函數?使用ILIKE如何在Sequelize中使用小寫字母函數Postgres
的findAll
是如下:
Db.models.Person.findAll(where: {firstName: {$ilike: `somename`}});
如何將其更改爲lower(firstname) = lower('somename');
PostgreSQL通常使用區分大小寫的排序規則。這意味着每個列中顯示的數據將與您的查詢進行字面比較。
您有幾種選擇:
1.按照本的答案,幷包裹在一個sequelize.fn('lower')
打電話給你的包裹欄和數據庫。
優點:無數據庫更改。
缺點:您需要記住爲每個查詢使用它。預測索引(除非您已經創建了functional index)並按順序掃描表,導致較慢的表查找。相當詳細的代碼。
2.使用ILIKE,以不區分大小寫匹配模式
爲準確找到的名稱:
Db.models.Person.findAll(where: {firstName: {$iLike: 'name'}});
爲了找到一個片段,其可以被包含在任意字符:
Db.models.Person.findAll(where: {firstName: {$iLike: '%name%'}});
優點:易於記憶。沒有Sequelize函數包裝器 - 它是一個內置的操作器,所以語法更簡潔。不需要特殊索引或數據庫更改。
缺點:速度慢,除非你使用擴展搞亂像pg_trgm
3。
select * from people where name = 'DAVID'
定義列類型爲「citext」(而不是text
或character varying
)有把這個相同的實際效果定義你的文本列
這個...
select * from people where LOWER(name) = LOWER('DAVID')
PostgreSQL的documen塔季翁表示這是一個如何與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基本上是換出你的「文本」列「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
}
});
那麼你的搜索對該列將總是與常規不區分大小寫where =
查詢
優點:無需包裝您的查詢在醜陋的sequelize.fn
調用。不需要記住顯式小寫。區域識別,因此適用於所有字符集。
缺點:您需要記住使用它在你的Sequelize定義首先定義表時。始終激活 - 您需要知道在定義表格時您需要執行不區分大小寫的搜索。
我通過以下遷移完成了第三個解決方案。可能爲其他有用:module.exports = { 起來:函數(的QueryInterface,Sequelize){ queryInterface.sequelize.query( '創建擴展IF NOT存在具有SCHEMA公共citext;'); (''CREATE TABLE mytable(email CITEXT PRIMARY KEY NOT NULL,password TEXT NOT NULL);'); }, 向下:函數(的QueryInterface,Sequelize){ 的QueryInterface。DROPTABLE( 'MYTABLE'); } }; – Andreas
您可以在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');
使用這種方式,當我需要搜索多個參數時,我應該怎麼做。 例如:姓氏和電話號碼。 lastName是類似於firstName的字段類型,phoneNumber是存儲數字的字段。 – spyalert01
您只需將它們正常添加到您的'where:{}'對象。 '其中:{ sequelize.where(sequelize.fn( '低',sequelize.col( '姓名')),sequelize.fn( '下', 'somename')), 電話號碼:8435551212 }' –
@Ben:這不是爲我工作,我建議:'其中:{電話號碼: '8435551212',$西:sequelize.where(sequelize.fn( '下',sequelize.col( '名字')),sequelize .fn('lower','somename'))}' – kwarnke
不知道是否適用於你,但在我的情況下,我嘗試使用在C#中的LINQ unaccent功能並且不可能使它工作,在剛剛結束創建新列'u_column'和使用Postgres的函數來填充它。沒有preatty但工作。 –