隨意獲取您發現有用的任何代碼。或者更好的是,您非常歡迎您成為一名維護者!對於放任這個項目的最深切的道歉。我希望這不會給您帶來任何不便。
postgres在node.js中使用semelize作為其ORM。
查看代碼示例。
該庫利用Postgres全文搜索和實現的視圖來快速,功能強大且簡單的搜索查詢。它首先通過將要搜索的字段中的所有值串聯並將它們轉換為ts_vector來創建實現的視圖。然後,它將searchByText和search類方法添加到您的續集模型中,這使您只能從查詢字符串或查詢字符串和選項JSON對象運行搜索。它還添加了一種refresh類方法,可以在對模型進行更新或隨時隨地進行更新時刷新實現的視圖。
例如,假設我們有一個膠片數據庫表,該表有:
| ID | 姓名 | 描述 | 城市 | Release_date | 等級 |
|---|---|---|---|---|---|
| 1 | 逃犯 | 另一個人逃離監獄 | 芝加哥 | 1993-08-06 | 8 |
| 2 | 美麗的頭腦 | 一部關於數學家的電影 | 紐約 | 2001-12-05 | 8 |
| 3 | 芝加哥 | 一部好OL'美國音樂劇 | 多倫多 | 2002-12-10 | 7 |
| 4 | 一塵不染的永恆陽光 | 吉姆·卡里(Jim Carrey)不是喜劇演員 | 紐約 | 2004-03-19 | 8 |
我們希望允許按名稱,描述和城市搜索,並通過評分和reaker_date進行過濾。我們還希望通過相關性來對結果進行分類,從而使名稱字段的權重高於描述和城市。因此,如果您運行搜索:
Film . searchByText ( "Chicago" ) ; // Returns [ Chicago, The Fugitive ]標題中帶有“芝加哥”一詞的結果出現在描述或城市中具有相同單詞的人面前。因此,電影芝加哥將首先出現,逃犯將是第二部。
我們還可以通過某個字段添加過濾和訂購,而不是通過進行搜索查詢來訂購相關性:
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 ]您也不僅限於一個模型的字段;您也可以包括關聯模型的字段。例如,如果我們在數據庫中有另一個模型,該模型稱為Actor,該模型與外鍵相關的膠片相關,我們可以包括來自Actor模型的字段,以在膠片實體視圖中。這使我們能夠運行搜索,例如:
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) 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" ] ]
}不要忘記刷新實現的視圖,以對模型進行的最新更改進行更新。一種方法是在您的模型上創建餘寫,刷新和刪除後的掛鉤,以刷新物有所值的視圖:
sequelize . define ( 'Film' , attributes , {
hooks : {
afterCreate : ( ) => FilmMaterializedView . refresh ( ) ,
afterUpdate : ( ) => FilmMaterializedView . refresh ( ) ,
afterDelete : ( ) => FilmMaterializedView . refresh ( )
}
} ) ;另外,您可以擁有一個工作調度程序,可以每X量的時間刷新您的實現視圖。
前往文檔部分,了解您可以進行哪種搜索。
PG搜索 - 續集有2個類, SearchModel和QueryInterface 。
SearchModel模型類是您用來將搜索和刷新類方法添加到實現的視圖續集模型的方法。要訪問require("pg-search-sequelize") SearchModel -seperize”) 。可以從您使用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 - 第一個值的數組是屬性名稱,第二個是方向。例如: 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屬性或實現視圖模型定義中的所有屬性的搜索結果實例。
刷新物有的視圖。前任。 models.Film.afterCreate(() => MaterializedViews.Film.refresh())
QueryInterface類是用於運行遷移的;即創建和刪除物有的視圖。 up queryInterface QueryInterface down require("pg-search-sequelize").QueryInterface
let QueryInterface = require ( "pg-search-sequelize" ) . QueryInterface ;
module . exports = {
up : queryInterface => new QueryInterface ( queryInterface ) . createMaterializedView ( ... ) ,
down : queryInterface => new QueryInterface ( queryInterface ) . dropMaterializedView ( ... ) ,
} ; 在數據庫中創建一個具有兩個字段的新型視圖; 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 - 指向相關模型的外國基金會。請注意,基於關聯類型,外鍵可以在參考模型(示例中的薄膜模型)或其他模型(Actor模型)上。targetKey外國關鍵的關鍵。associationType - 參考模型(電影)角度的關聯類型。它必須是hasOne , hasMany或belongsTo 。attributes - 從模型中包含的屬性。include - 與隨附模型相關的一系列模型(與Actor相關的模型) 丟下物化的視圖。
name - 實現的視圖的名稱