لا تتردد في الحصول على أي قطع من الكود تجدها مفيدة. أو الأفضل من ذلك ، فأنت أكثر من مرحبًا بك لتصبح مشرفًا! أعمق أعمق اعتذاري عن ترك هذا المشروع يذهب. آمل ألا يسبب لك أي إزعاج.
Postgres Search Full Text في Node.js باستخدام تتمة مثل ORM.
تحقق من مثال الرمز.
تستفيد هذه المكتبة من البحث عن النص Postgres والمسافات المتكاملة لتشغيل استعلامات بحث سريعة وقوية وبسيطة. يقوم أولاً بإنشاء طريقة عرض تجسيد من خلال تسلسل جميع القيم في الحقول التي تريد أن تجعلها قابلة للبحث وتحويلها إلى ts_vector . ثم يضيف أساليب searchByText و search إلى طراز التسلسل الخاص بك ، والذي يمكّنك من تشغيل عمليات البحث من سلسلة استعلام فقط ، أو سلسلة استعلام وكائن JSON خيارات. كما أنه يضيف طريقة فئة refresh لتحديث العرض الملموس عند إجراء التحديثات إلى النموذج الخاص بك أو وقتما تشاء.
على سبيل المثال ، دعنا نفترض أن لدينا جدول قاعدة بيانات الأفلام الذي يحتوي على:
| بطاقة تعريف | اسم | وصف | مدينة | تاريخ الافراج عنه | تصنيف |
|---|---|---|---|---|---|
| 1 | الهارب | رجل آخر يهرب من السجن | شيكاغو | 1993-08-06 | 8 |
| 2 | عقل جميل | فيلم عن عالم الرياضيات | نيويورك | 2001-12-05 | 8 |
| 3 | شيكاغو | موسيقي أم أمريكي جيد | تورونتو | 2002-12-10 | 7 |
| 4 | أشعة الشمس الأبدية للعقل الناصع | جيم كاري عندما لا يكون كوميديًا | نيويورك | 2004-03-19 | 8 |
نريد السماح بالبحث بالاسم والوصف والمدينة ، والتصفية عن طريق التصنيف والإصدار. نريد أيضًا فرز النتائج حسب الأهمية عن طريق منح حقل الاسم وزنًا أعلى من الوصف والمدينة. لذلك إذا قمت بتشغيل البحث:
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 ]أنت أيضًا لا تقتصر على حقول نموذج واحد فقط ؛ يمكنك تضمين الحقول من النماذج المرتبطة أيضًا. على سبيل المثال ، إذا كان لدينا نموذج آخر في قاعدة البيانات الخاصة بنا يسمى الممثل الذي يرتبط بالفيلم من قبل مفتاح خارجي ، فيمكننا تضمين الحقول من نموذج الممثل ليكون في عرض الفيلم. هذا يسمح لنا بتشغيل عمليات البحث مثل:
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.يرجى الرجوع إلى الاستخدام لكيفية تحديد النموذج الخاص بك وكيفية إنشاء طريقة العرض المتكافئة.
الآن بعد أن حصلت على نظرة خاطفة على ما تمكنك هذه المكتبة في النهاية ، دعنا نصل إلى خطوات الإعداد:
إذا كنت تستخدم أداة Migrations Sequelize ، فيمكنك استخدام وظيفة المساعد 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 Search - Sequelize يحتوي على فئتين ، SearchModel و QueryInterface .
فئة SearchModel هي ما تستخدمه لإضافة أساليب البحث والتحديث إلى طراز Sequelize Model الخاص بك. للوصول إلى فئة 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 مخصصة لتشغيل الترحيل ؛ أي إنشاء وإسقاط العرض الملمس. للوصول إلى فئة QueryInterface require("pg-search-sequelize").QueryInterface في وظائف up down ، قم بإنشاء مثيل ونقل إليه queryInterface : Sequelize:
let QueryInterface = require ( "pg-search-sequelize" ) . QueryInterface ;
module . exports = {
up : queryInterface => new QueryInterface ( queryInterface ) . createMaterializedView ( ... ) ,
down : queryInterface => new QueryInterface ( queryInterface ) . dropMaterializedView ( ... ) ,
} ; ينشئ طريقة عرض جديدة ملموسة في قاعدة البيانات التي تحتوي على حقلين ؛ معرف ووثائق. حقل المستند هو 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 - The Foreignkey التي تشير إلى النموذج المرتبط. لاحظ أنه بناءً على نوع الارتباط ، يمكن أن يكون المفتاح الخارجي على النموذج المرجعي (نموذج الفيلم في المثال أعلاه) أو على النموذج الآخر (نموذج الممثل).targetKey - المفتاح الذي يشير إليه الأجنبي.associationType - نوع الارتباط من منظور النموذج المرجعي (فيلم). يجب أن يكون hasOne أو hasMany أو belongsTo .attributes - السمات التي يجب تضمينها من النموذج.include - تشمل مجموعة من النماذج المرتبطة بالنموذج المضمن (النماذج السابقين المرتبطة بالممثل) يسقط العرض الملمس.
name - اسم العرض الملمس