mongoose-fuzzy-searching は、MongoDB 内のドキュメントのあいまい検索を可能にするシンプルで軽量のプラグインです。このコードはこの記事に基づいています。
npmを使用してインストールする
$ npm i mongoose-fuzzy-searching
または糸を使って
$ yarn add mongoose-fuzzy-searching
開始する前に、ベスト プラクティスを実行して問題を回避するために、すべての非推奨の警告を正しく処理してください。
プラグインにインデックスを作成させるには、 useCreateIndex
true に設定する必要があります。以下の例は、データベースに接続する方法を示しています。
const options = {
useNewUrlParser : true ,
useUnifiedTopology : true ,
useFindAndModify : false ,
useCreateIndex : true ,
} ;
mongoose . Promise = global . Promise ;
return mongoose . connect ( URL , options ) ;
以下の例では、 User
コレクションがあり、 firstName
とlastName
であいまい検索を実行したいと考えています。
const { Schema } = require ( 'mongoose' ) ;
const mongoose_fuzzy_searching = require ( 'mongoose-fuzzy-searching' ) ;
const UserSchema = new Schema ( {
firstName : String ,
lastName : String ,
email : String ,
age : Number ,
} ) ;
UserSchema . plugin ( mongoose_fuzzy_searching , { fields : [ 'firstName' , 'lastName' ] } ) ;
const User = mongoose . model ( 'User' , UserSchema ) ;
module . exports = { User } ;
const user = new User ( { firstName : 'Joe' , lastName : 'Doe' , email : '[email protected]' , age : 30 } ) ;
try {
await user . save ( ) ; // mongodb: { ..., firstName_fuzzy: [String], lastName_fuzzy: [String] }
const users = await User . fuzzySearch ( 'jo' ) ;
console . log ( users ) ;
// each user object will not contain the fuzzy keys:
// Eg.
// {
// "firstName": "Joe",
// "lastName": "Doe",
// "email": "[email protected]",
// "age": 30,
// "confidenceScore": 34.3 ($text meta score)
// }
} catch ( e ) {
console . error ( e ) ;
}
結果は、 confidenceScore
キーによって並べ替えられます。このオプションはオーバーライドできます。
try {
const users = await User . fuzzySearch ( 'jo' ) . sort ( { age : - 1 } ) . exec ( ) ;
console . log ( users ) ;
} catch ( e ) {
console . error ( e ) ;
}
オプションにはfields
とmiddlewares
含めることができます。
Fields 属性は必須であり、 Strings
の配列またはObjects
の配列のいずれかである必要があります。
すべてのフィールドにデフォルトのオプションを使用したい場合は、それらを文字列として渡すだけです。
const mongoose_fuzzy_searching = require ( 'mongoose-fuzzy-searching' ) ;
const UserSchema = new Schema ( {
firstName : String ,
lastName : String ,
email : String ,
} ) ;
UserSchema . plugin ( mongoose_fuzzy_searching , { fields : [ 'firstName' , 'lastName' ] } ) ;
引数のデフォルト オプションをオーバーライドしたい場合は、それらをオブジェクトとして追加し、必要な値をオーバーライドできます。以下の表には、このオブジェクトに必要なキーが含まれています。
鍵 | タイプ | デフォルト | 説明 |
---|---|---|---|
名前 | 弦 | ヌル | コレクションキー名 |
最小サイズ | 整数 | 2 | N グラムの最小サイズ。 Nグラムについて詳しく見る |
重さ | 整数 | 1 | テキスト検索スコアの観点から、他のインデックス付きフィールドと比較したフィールドの重要性を示します。インデックスの重みについて詳しく見る |
プレフィックスのみ | ブール値 | 間違い | 単語の先頭からの ngram のみを返します。 (より正確な結果が得られます) |
エスケープ特殊文字 | ブール値 | 真実 | N-gram から特殊文字を削除します。 |
キー | 配列[文字列] | ヌル | コレクション属性のタイプがObject または[Object] の場合 (例を参照)、あいまい検索に使用する属性を定義できます。 |
例:
const mongoose_fuzzy_searching = require ( 'mongoose-fuzzy-searching' ) ;
const UserSchema = new Schema ( {
firstName : String ,
lastName : String ,
email : String ,
content : {
en : String ,
de : String ,
it : String
}
text : [
{
title : String ,
description : String ,
language : String ,
} ,
] ,
} ) ;
UserSchema . plugin ( mongoose_fuzzy_searching , {
fields : [
{
name : 'firstName' ,
minSize : 2 ,
weight : 5 ,
} ,
{
name : 'lastName' ,
minSize : 3 ,
prefixOnly : true ,
} ,
{
name : 'email' ,
escapeSpecialCharacters : false ,
} ,
{
name : 'content' ,
keys : [ 'en' , 'de' , 'it' ] ,
} ,
{
name : 'text' ,
keys : [ 'title' , 'language' ] ,
} ,
] ,
} ) ;
ミドルウェアは、カスタムのpre
ミドルウェアを含めることができるオプションのObject
です。このプラグインは、ファジー要素を作成または更新するためにこれらのミドルウェアを使用しています。つまり、 pre
ミドルウェアを追加しても、プラグインによってオーバーライドされるため、それらは呼び出されることはありません。この問題を回避するには、カスタム ミドルウェアをプラグインに渡すことができます。ミドルウェアが最初に呼び出されます。渡すことができるミドルウェアは次のとおりです。
schema.pre("save", ...)
の略です。schema.pre("insertMany", ...)
の略です。schema.pre("update", ...)
の略です。schema.pre("updateOne", ...)
の略です。schema.pre("findOneAndUpdate", ...)
の略です。schema.pre("updateMany", ...)
の略です。上記のミドルウェアを追加したい場合は、プラグインに直接追加できます。
const mongoose_fuzzy_searching = require ( 'mongoose-fuzzy-searching' ) ;
const UserSchema = new Schema ( {
firstName : String ,
lastName : String ,
} ) ;
UserSchema . plugin ( mongoose_fuzzy_searching , {
fields : [ 'firstName' ] ,
middlewares : {
preSave : function ( ) {
// do something before the object is saved
} ,
} ,
} ) ;
ミドルウェアは非同期関数にすることもできます。
const mongoose_fuzzy_searching = require ( 'mongoose-fuzzy-searching' ) ;
const UserSchema = new Schema ( {
firstName : String ,
lastName : String ,
} ) ;
UserSchema . plugin ( mongoose_fuzzy_searching , {
fields : [ 'firstName' ] ,
middlewares : {
preUpdateOne : async function {
// do something before the object is updated (asynchronous)
}
}
} ) ;
ファジー検索クエリは、 static
関数として、または複数のクエリを連結できるhelper
として使用できます。どちらの場合も関数名は、surprise、surprise、 fuzzySearch
です。
インスタンス メソッドは最大 3 つのパラメータを受け入れることができます。 1 つ目はクエリで、 String
またはObject
いずれかになります。このパラメータは必須です。 2 番目のパラメータは、追加のクエリ (例: age: { $gt: 18 }
) を含むObject
、またはコールバック関数のいずれかになります。 2 番目のパラメータがクエリの場合、3 番目のパラメータはコールバック関数です。コールバック関数を設定しない場合、結果は Promise 内で返されます。
以下の表には、最初のパラメータ ( がオブジェクトの場合) に必要なキーが含まれています。
鍵 | タイプ | デフォルトの | 説明 |
---|---|---|---|
クエリ | 弦 | ヌル | 検索する文字列 |
最小サイズ | 整数 | 2 | N グラムの最小サイズ。 |
プレフィックスのみ | ブール値 | 間違い | 単語の先頭からの ngram のみを返します。 (より正確な結果が得られます) プレフィックス |
ちょうど | ブール値 | 間違い | 個々の用語ではなくフレーズに一致します |
例:
/* With string that returns a Promise */
User . fuzzySearch ( 'jo' ) . then ( console . log ) . catch ( console . error ) ;
/* With additional options that returns a Promise */
User . fuzzySearch ( { query : 'jo' , prefixOnly : true , minSize : 4 } )
. then ( console . log )
. catch ( console . error ) ;
/* With additional queries that returns a Promise */
User . fuzzySearch ( 'jo' , { age : { $gt : 18 } } )
. then ( console . log )
. catch ( console . error ) ;
/* With string and a callback */
User . fuzzySearch ( 'jo' , ( err , doc ) => {
if ( err ) {
console . error ( err ) ;
} else {
console . log ( doc ) ;
}
} ) ;
/* With additional queries and callback */
User . fuzzySearch ( 'jo' , { age : { $gt : 18 } } , ( err , doc ) => {
if ( err ) {
console . error ( err ) ;
} else {
console . log ( doc ) ;
}
} ) ;
インスタンス メソッドに似ていますが、マングース クエリ用のヘルパー関数であるクエリを使用することもできます。クエリ ヘルパー メソッドを使用すると、mongoose のチェーン可能なクエリ ビルダー API を拡張できます。
クエリ ヘルパーは最大 2 つのパラメータを受け入れることができます。 1 つ目はクエリで、 String
またはObject
いずれかになります。このパラメータは必須です。 2 番目のパラメーターは、追加のクエリ (例: age: { $gt: 18 }
) を含むObject
にすることができますが、これはオプションです。このヘルパーはコールバック関数を受け入れません。関数を渡すとエラーがスローされます。クエリヘルパーの詳細。
例:
const user = await User . find ( { age : { $gte : 30 } } )
. fuzzySearch ( 'jo' )
. exec ( ) ;
プラグインは、選択したフィールドのインデックスを作成します。以下の例では、新しいインデックスはfirstName_fuzzy
とlastName_fuzzy
になります。また、各ドキュメントにはフィールドfirstName_fuzzy
[String] およびlastName_fuzzy
[String] があります。これらの配列には、選択したフィールドのアナグラムが含まれます。
const mongoose_fuzzy_searching = require ( 'mongoose-fuzzy-searching' ) ;
const UserSchema = new Schema ( {
firstName : String ,
lastName : String ,
email : String ,
age : Number ,
} ) ;
UserSchema . plugin ( mongoose_fuzzy_searching , { fields : [ 'firstName' , 'lastName' ] } ) ;
つまり、このプラグインはドキュメントを作成または更新するときにアナグラムを作成します。既存のすべてのドキュメントにはこれらのファジー配列が含まれていないため、 fuzzySearch
関数はそれらを見つけることができません。
既存のドキュメントのアナグラムを作成するには、各ドキュメントを更新する必要があります。以下の例では、コレクションUser
のすべてのドキュメントのfirstName
属性を更新します。
const cursor = Model . find ( ) . cursor ( ) ;
cursor . next ( function ( error , doc ) {
const obj = attrs . reduce ( ( acc , attr ) => ( { ... acc , [ attr ] : doc [ attr ] } ) , { } ) ;
return Model . findByIdAndUpdate ( doc . _id , obj ) ;
} ) ;
前の例では、 firstName
とlastName
ファジー属性として設定しました。ファジー フィールドからfirstName
削除しても、 firstName_fuzzy
配列はコレクションによって削除されません。各ドキュメントの配列を削除したい場合は、その値の設定を解除する必要があります。
const cursor = Model . find ( ) . cursor ( ) ;
cursor . next ( function ( error , doc ) {
const $unset = attrs . reduce ( ( acc , attr ) => ( { ... acc , [ ` ${ attr } _fuzzy` ] : 1 } ) , { } ) ;
return Model . findByIdAndUpdate ( data . _id , { $unset } , { new : true , strict : false } ) ;
} ) ;
すべての単体テストと統合テストに jest を使用します。
$ npm test
注: これにより、データベース上での複数の同時接続を避けるために、すべてのスイートがシリアルに実行されます。
これにより、メモリ データベースを使用してテストが実行されます。何らかの理由で、mongo インスタンス上で実際の接続を使用してテストを実行したい場合は、環境変数MONGO_DB
を追加します。
$ docker run --name mongo_fuzzy_test -p 27017:27017 -d mongo
$ MONGO_DB=true npm test
$ npm run test:unit
$ npm run test:integration
MITライセンス
著作権 (c) 2019 ヴァシリス・パラス
本ソフトウェアおよび関連ドキュメント ファイル (以下「ソフトウェア」) のコピーを入手した人には、使用、コピー、変更、マージする権利を含むがこれらに限定されない、制限なくソフトウェアを取り扱う許可が、ここに無償で与えられます。 、以下の条件を条件として、本ソフトウェアのコピーを出版、配布、サブライセンス、および/または販売すること、および本ソフトウェアが提供される人物にそれを許可すること。
上記の著作権表示およびこの許可通知は、ソフトウェアのすべてのコピーまたは主要部分に含まれるものとします。
ソフトウェアは「現状のまま」提供され、明示的か黙示的かを問わず、商品性、特定目的への適合性、および非侵害の保証を含むがこれらに限定されない、いかなる種類の保証も行われません。いかなる場合においても、作者または著作権所有者は、契約行為、不法行為、またはその他の行為であるかどうかにかかわらず、ソフトウェアまたはソフトウェアの使用またはその他の取引に起因または関連して生じる、いかなる請求、損害、またはその他の責任に対しても責任を負わないものとします。ソフトウェア。