2016-01-12 43 views
6

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

findAll次のように:

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

私はlower(firstname) = lower('somename');

+0

あなたには当てはまりませんが、私の場合はC#linqでunaccent関数を使ってみました。最後には新しい列 'u_column'を作成し、それを埋めるためにpostgres関数を使います。 Wasnt preattyしかし仕事。 –

答えて

13

PostgreSQLでは、通常、大文字と小文字を区別する照合が使用されます。これは、各列に表示されるデータが文字通りクエリと比較されることを意味します。

あなたは、いくつかのオプションがあります:


1.フォローベンの答え、およびsequelize.fn('lower')コールであなたのラップ列とデータベースをラップします。

長所:データベースは変更されません。

短所:すべてのクエリで使用することを忘れないでください。 Foregoesのインデックス(既にfunctional indexを作成していない場合)は、テーブルを順番にスキャンするため、大きなテーブルのルックアップが遅くなります。かなり冗長なコード。

Db.models.Person.findAll(where: {firstName: {$iLike: 'name'}});

内に収容することができる断片を検索する:大文字小文字を区別せずに正確に名前を見つけるためにパターンを

と一致


2. ILIKE、任意の文字:

Db.models.Person.findAll(where: {firstName: {$iLike: '%name%'}});

長所:覚えやすい。 No Sequelize関数ラッパー - ビルトイン演算子なので、構文はそれほど役に立ちません。特殊な索引やデータベースの変更は必要ありません。

短所:スロー、あなたがpg_trgm


3のような拡張子をいじり始める場合を除きます。

select * from people where name = 'DAVID'

:暗黙的に(代わりにtextまたはcharacter varyingの)「citext」これを回すのと同じ実用的な効果を持っているとして、あなたの列の型を定義小文字

を比較citextタイプ、を使用してテキスト列を定義します。これに

...

select * from people where LOWER(name) = LOWER('DAVID')

PostgreSQLのdocumen tationが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でそれを使用する各データベース上でそれを有効にする必要があります:次に

// Assuming `Conn` is a new Sequelize instance 
const Person = Conn.define('person', { 
    firstName: { 
    allowNull: false, 
    type: 'citext' // <-- this is the only change 
    } 
}); 

検索を反対:あなたのSequelize定義で

CREATE EXTENSION IF NOT EXISTS citext WITH SCHEMA public;

そして、type属性を定義しますクエリをラップする必要はありません:その列は常に大文字と小文字を区別しない正規のwhere =

専門家に照会されます醜いsequelize.fn呼び出しで。明示的に小文字を覚える必要はありません。ロケールを認識するので、すべてのキャラクタセットで機能します。

短所:最初にテーブルを定義する際にSequelize定義で使用することを覚えておく必要があります。常にアクティブにする - テーブルを定義する際に、大文字と小文字を区別しない検索を行う必要があることを知る必要があります。

+0

次の移行で3番目の解決策を実行しました。他の人にとって役に立つかもしれません:module.exports = { up:function(queryInterface、Sequelize){ queryInterface.sequelize.query( '存在しないと拡張を作成します。queryInterface.sequelize.query( 'CREATE TABLE mytable(電子メールCITEXT PRIMARY KEY NOT NULL、パスワードTEXT NOT NULL);'); }、 down:function(queryInterface、Sequelize){ queryInterface。dropTable( 'mytable'); } }; – Andreas

2

にそれを変更するにはどうすればよいあなたは、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'); 
+1

このようにして、何とか何とかしようと思ったら、どうすればいいですか? 例:lastNameおよび電話番号。ここで、lastNameはfirstNameのようなフィールドの似ていますが、phoneNumberは数字を格納するフィールドです。 – spyalert01

+0

あなたは 'where:{}'オブジェクトに通常のように追加するだけです。 ':{ sequelize.where(sequelize.fn( '下部'、sequelize.col))( 'FIRSTNAME'、sequelize.fn( '下部'、 'somenameの'))、 にphoneNumber:8435551212 }' –

+1

@Ben:これは私のためには機能しません、私は示唆しています: ':{phoneNumber: '8435551212'、$ col:sequelize.where(sequelize.fn( 'lower'、sequelize.col( 'firstname'))、sequelize .fn( 'lower'、 'somename'))} ' – kwarnke

関連する問題