便利だと思われるコードを自由につかんでください。または、さらに良いことに、あなたはメンテナーになることを歓迎しています!このプロジェクトを手放したことを誠実に謝罪します。ご不便をおかけしないことを願っています。
ormとしてたときを使用して、node.jsでのフルテキスト検索をpostgresします。
コードの例をご覧ください。
このライブラリは、Postgresフルテキスト検索と具体化されたビューを使用して、高速で強力な、シンプルな検索クエリを実行します。最初に、検索可能にしたいフィールドのすべての値を連結し、それらをts_vectorに変換することにより、具体化されたビューを作成します。次に、 searchByTextとsearchクラスのメソッドを「Cory Stringのみ」またはクエリ文字列とOptions JSONオブジェクトから検索を実行できるようにするモデルにClassメソッドを検索します。また、モデルに更新が行われたとき、またはいつでも必要なときに、具体化されたビューを更新するためのrefreshクラスのメソッドを追加します。
たとえば、以下を備えたフィルムデータベーステーブルがあると仮定しましょう。
| id | 名前 | 説明 | 市 | 発売日 | 評価 |
|---|---|---|---|---|---|
| 1 | 逃亡者 | 別の男が刑務所から逃げます | シカゴ | 1993-08-06 | 8 |
| 2 | 美しい心 | 数学者に関する映画 | ニューヨーク | 2001-12-05 | 8 |
| 3 | シカゴ | 古き良きアメリカのミュージカル | トロント | 2002-12-10 | 7 |
| 4 | きれいな心の永遠の太陽 | ジム・キャリーはコメディアンではないとき | ニューヨーク | 2004-03-19 | 8 |
名前、説明、都市で検索し、評価とrelease_dateでフィルタリングすることを許可します。また、名前のフィールドに説明や都市よりも高い重量を与えることにより、結果を関連性によって並べ替えたいと考えています。したがって、検索を実行した場合:
Film . searchByText ( "Chicago" ) ; // Returns [ Chicago, The Fugitive ]タイトルの「シカゴ」という言葉が、説明や都市に同じ単語がある人の前に表示される結果。したがって、映画は最初に登場し、逃亡者は2番目になります。
また、検索クエリを作成することにより、関連性によって注文する代わりに、特定のフィールドでフィルタリングと注文を追加することもできます。
Film . searchByText ( "Mind order:releaseDate" ) ; // Returns [ A Beautiful Mind, Eternal Sunshine of the Spotless Mind ]
// or
Film . searchByText ( "Mind releaseDate:<2002-01-01" ) ; // Returns [ A Beautiful Mind ]また、1つのモデルのフィールドのみに限定されません。関連するモデルのフィールドも含めることができます。たとえば、外部キーによってフィルムに関連付けられている俳優と呼ばれる別のモデルがある場合、映画の具体化されたビューにある俳優モデルのフィールドを含めることができます。これにより、次のような検索を実行できます。
Film . searchByText ( "Tom Hanks" ) ; // Returns Tom Hanks moviesこのライブラリでできることはもっとあります。インストールと使用方法の詳細については、インストールと使用法のセクションをご覧ください。ドキュメントについては、ドキュメントセクションをご覧ください。
NPM pg-search-sequelizeパッケージをインストールします
npm i --save pg-search-sequelize次に、具体化されたビューモデル定義ファイルでそれを要求し、それを使用可能にするために後遺症のモデルを渡します。
let MyModel = sequelize . define ( ... ) ; // your sequelize model definition
let SearchModel = require ( 'pg-search-sequelize' ) ; // Require the pg-search-sequelize library
MyModel = new SearchModel ( MyModel ) ; // Construct a SearchModel out of the model you defined above. This adds `search`, `searchByText`, and `refresh` class methods to your model.モデルを定義する方法と、具体化されたビューを作成する方法については、使用法を参照してください。
このライブラリが最終的にあなたを可能にするものをこっそり覗いてみたので、セットアップ手順に到達しましょう。
createMaterializedView(name, referenceModel, attributes, options)ヘルパー機能を使用すると、CreateMaterializedView( QueryInterface )を使用できます。
const QueryInterface = require ( "pg-search-sequelize" ) . QueryInterface ;
const models = require ( "../models" ) ;
// The model we're creating the materialized view for
const referenceModel = models . Film ;
const materializedViewName = "film_materialized_view" ;
const attributes = { // field: weight. Every field has a weight to calculate how relevant the search results are.
name : "A" , // name has the highest weight.
description : "B" ,
city : "C" // city has a lower weight than title and description
}
const options = {
include : [ // You can also include fields from associated models
{
model : models . Actor ,
foreignKey : "actor_id" ,
targetKey : "id" ,
associationType : "hasMany" , // association types are: belongsTo, hasOne, or hasMany
attributes : { // Those attributes get added to the materialized view's search document and will also be searched just like the other fields
first_name : "D" ,
last_name : "D" ,
date_of_birth : "D"
}
}
]
}
module . exports : {
up : queryInterface => new QueryInterface ( queryInterface ) . createMaterializedView ( materializedViewName , referenceModel , attributes , options ) ,
down : queryInterface => new QueryInterface ( queryInterface ) . dropMaterializedView ( materializedViewName )
}後遺症の移行ツールを使用しない場合は、どんな方法でも具体化されたビューを自由に作成してください。
他の後遺症モデルを定義するのと同じ方法で、具体化されたビューのモデルを定義します。唯一の違いは、モデル定義オプションにreferenceModelプロパティを追加する必要があることです。次に、定義したばかりの具体化されたビューモデルからSearchModelを作成するだけです。
let SearchModel = require ( "pg-search-sequelize" ) ;
let FilmMaterializedView = sequelize . define ( 'FilmMaterializedView' , {
name : DataTypes . STRING ,
rating : DataTypes . INTEGER ,
document : DataTypes . TEXT
} , {
referenceModel : models . Film // The model for which we're defining the materialized view
} ) ;
FilmMaterializedView = new SearchModel ( FilmMaterializedView ) ; // Adds search, searchByText, and refresh class methods to the model.これでmaterializedViewModel.search(query, options)またはmaterializedViewModel.searchByText(query)を呼び出して、モデルとその関連付けでフルテキスト検索を実行できます。
models . Film . searchByText ( "Mind" ) ; // Returns [ A Beautiful Mind, Eternal Sunshine of the Spotless Mind ]
// The following command searches for instances that match the search query,
// filters by those with releaseDate later than 2002, and orders the results by name field
models . Film . searchByText ( "Mind releaseDate:>2002 order:name" ) ; // Returns [ Eternal Sunshine of the Spotless Mind ]
// Or if you don't like strings, you can pass those properties in a JSON object
// The following returns the same as the code above; i.e. [ Eternal Sunshine of the Spotless Mind ]
models . Film . search ( "Mind" , {
where : {
releaseDate : { operator : ">" , value : "2002-01-01" }
} ,
order : [ [ "name" , "ASC" ] ]
}具体化されたビューを更新して、モデルに加えた最新の変更で更新することを忘れないでください。それを行う1つの方法は、モデルにAfterCreate、AfterUpdate、およびAfterdeleteフックを作成して、具体化されたビューを更新することです。
sequelize . define ( 'Film' , attributes , {
hooks : {
afterCreate : ( ) => FilmMaterializedView . refresh ( ) ,
afterUpdate : ( ) => FilmMaterializedView . refresh ( ) ,
afterDelete : ( ) => FilmMaterializedView . refresh ( )
}
} ) ;または、Xの時間ごとに具体化されたビューを再リッシュするジョブスケジューラを持つことができます。
ドキュメントセクションにアクセスして、どのような検索を行うことができるかをご覧ください。
PG Search -Sequelizeには、 SearchModelとQueryInterface 2つのクラスがあります。
SearchModelクラスは、具体化されたビューモデルにクラスメソッドを検索とリフレッシュするために使用するものです。 SearchModelクラスrequire("pg-search-sequelize")アクセスするには)。以下の機能は、SearchModelクラスで構築するモデルから呼び出すことができますMyModel = new SearchModel(MyModel)
検索クエリ文字列とオプションオブジェクトを使用して、マテリアルビューモデルを検索します。
query - 検索クエリ文字列。optionswhere - 結果を制限するフィルター。 /*
Format:
options.where = {
attribute: {
operator: ">, <, =, >=, <=, @@, ilike, etc.",
value: "some value"
}
*/
// Example:
options . where = {
releaseDate : {
operator : ">" ,
value : "2012-01-01"
}
}attributes - 返す属性の配列。元。 options . attributes = [ "name" , "releaseDate" , "rating" ]order - 最初の値が属性名で、2番目の配列は方向です。例えば: options . order = [
[ "name" , "ASC" ] ,
[ "releaseDate" , "DESC" ] ,
[ "rating" , "DESC" ]
] Promise - オプションオブジェクトで指定された属性、マテリアルビューモデルのdefaultScope 、またはマテリアルビューモデル定義のすべての属性を含む検索結果インスタンスの配列。
テキストクエリのみでマテリアルビューモデルを検索します。これは、検索APIエンドポイントをモデルに公開するのに特に役立つため、検索クエリ文字列の解析を心配する必要はありません。
query - 注文するクエリテキスト、フィルター、およびフィールドの文字列。 // --------------
// Simple search
// --------------
Film . searchByText ( "Beautiful" ) ; // WHERE to_tsquery('Beautiful') @@ document
// --------------
// Ordering
// --------------
// Search and order the results by rating in ascending order
Film . search ( "Beautiful order:rating" ) ; // WHERE to_tsquery('Beatiful') @@ document ORDER BY ts_rank(document, to_tsquery('Beautiful')), rating ASC
// Or to invert the order to descending order, prepend the field name by an exclamation point
Film . searchByText ( "Beautiful order:!rating" ) ; // WHERE to_tsquery('Beatiful') @@ document ORDER BY ts_rank(document, to_tsquery('Beautiful')), rating DESC
// --------------
// Filtering
// --------------
// Searches for a movie that has the text "Beautiful" in any of its fields and "brilliant mathematician" in the description.
Film . searchByText ( "Beatiful description:brilliant mathematician" ) ; // WHERE to_tsquery('Beatiful') @@ document AND description ILIKE %brilliant mathematician%
// You can also use comparison operators: =, >, <. >=, <=
Film . searchByText ( "Beautiful rating:>=7" ) // WHERE to_tsquery('Beautiful') @@ document AND rating >= 7
// If no operator is passed to the filter, an ILIKE operator is used. Just as seen in the first filtering example.
// If the field's type doesn't work with ILIKE, it is cast to TEXT.
Film . searchByText ( "Beautiful releaseDate:200" ) // WHERE to_tsquery('Beautiful') @@ document AND release_date::TEXT ILIKE 200 PromiseマテリアルビューモデルのdefaultScope属性、またはマテリアルビューモデル定義のすべての属性を備えた検索結果インスタンスの配列。
具体化されたビューをresedします。元。 models.Film.afterCreate(() => MaterializedViews.Film.refresh())
QueryInterfaceクラスは、移行を実行するためのものです。つまり、具体化されたビューを作成してドロップします。 QueryInterfaceクラスにアクセスするにはrequire("pg-search-sequelize").QueryInterface up downのQueryInterfaceを作成し、インスタンスを構築して、後期queryInterfaceを渡します。
let QueryInterface = require ( "pg-search-sequelize" ) . QueryInterface ;
module . exports = {
up : queryInterface => new QueryInterface ( queryInterface ) . createMaterializedView ( ... ) ,
down : queryInterface => new QueryInterface ( queryInterface ) . dropMaterializedView ( ... ) ,
} ; 2つのフィールドを持つデータベースに新しい具体化されたビューを作成します。 IDとドキュメント。ドキュメントフィールドは、検索可能なすべての指定された属性/フィールドの連結テキストのts_vectorです
name - 具体化されたビューの名前model - 具体化されたビューを作成するテーブルのモデル。attributes - キー値のペアオブジェクトは、フィールドの名前とフィールドの重量の値です。 attributes = {
name : "A" // "A" is the highest weight
description : "B" ,
release_date : "C"
city : "D" // "D" is the lowest possible weight
}options tableName提供されれば、合格モデルのtableNameをオーバーライドします
primaryKeyField提供されれば、合格モデルのprimaryKeyFieldをオーバーライドします
include - 関連するモデルの属性を定義するオブジェクトの配列を、具体化されたビューのドキュメントに含める。
include = [
{
model : models . Actor ,
foreignKey : "actor_id" ,
target_key : "id" ,
associationType : "hasMany" ,
attribtues : {
first_name : "C" ,
last_name : "C"
} ,
include : [ ... ] // optionally you can include models associated to the Actor model
} ,
// ...
// Other associated models
]model - 含めるモデルforeignKey関連するモデルを指すforeignkey。アソシエーションタイプに基づいて、外部キーは参照モデル(上記の例のフィルムモデル)または他のモデル(俳優モデル)にある可能性があることに注意してください。targetKey - foreigrameyが参照する鍵。associationType参照モデル(フィルム)の観点からの関連タイプ。それはhasOne 、 hasMany 、またはbelongsToでなければなりません。attributes - モデルから含める属性。include - 含まれているモデルに関連付けられたモデルの配列を含める(俳優に関連付けられているモデル) 具体化されたビューをドロップします。
name - 具体化されたビューの名前