随意获取您发现有用的任何代码。或者更好的是,您非常欢迎您成为一名维护者!对于放任这个项目的最深切的道歉。我希望这不会给您带来任何不便。
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模型类是您用来将搜索和刷新类方法添加到实现的视图续集模型的方法。要访问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 - 第一个值的数组是属性名称,第二个是方向。例如: 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 - 实现的视图的名称