web-dev-qa-db-ja.com

Sequelize Postgresで小文字関数を使用する方法

小文字関数を使用してSequelizeで文字列検索を実行しようとしています。 ilikeを使ってなんとかします。私の質問は、このシナリオで小文字の関数を使用する方法ですか?

Ilikeを使用したfindAllは次のとおりです。

_Db.models.Person.findAll(where: {firstName: {$ilike: `somename`}});
_

lower(firstname) = lower('somename');に変更するにはどうすればよいですか

12
spyalert01

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。 citext タイプでテキスト列を定義します。これは暗黙的に小文字を比較します

textまたは_character varying_の代わりに)列タイプを 'citext'として定義すると、これを有効にする同じ効果があります。

_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は、基本的に「テキスト」列を「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定義でそれを使用することを忘れないでください。常にアクティブ化-テーブルを定義するときに、大文字と小文字を区別しない検索を実行することを知っておく必要があります。

25
Lee Benson

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');
7
Ben Polge