Parse Queryでとは書きましたが、mongodbベースのシステムなら応用できるかもしれません。ユーザの入力値をもとにDBからなんらかのデータを取得しようとするとき、基本的には完全一致でselectしますよね。しかし稀に人によって単語の使い方が異なるといった揺れがある場合があります。枚挙にいとまがありませんが、よくみるのはこんなところでしょうか。
Contents
よくある揺れの例
デジタル<->ディジタル
コンバージョン<->コンヴァージョン
ジレンマ<->ディレンマ
サービス<->サーヴィス
グルジア<->ジョージア
ヨルダン<->ジョーダン
一般的な単語ならまだしも、外国語の固有名詞を無理やりカタカナに変換すると上記のような例が頻発することなります。オリジナルの単語はあるものの、読み方はひとそれぞれ、というパターンですね。意外とこれが曲者で当人が意図した検索結果にならない元凶となっています。せっかく検索をしたものの、何もヒットしないとなると寒いですよね。そういう悲しい事故を減らすためにあいまい検索を実装する必要がでてきます。
Googleとかは類語とかもしっかりヒットしていてすごいなと思う一方で、さすがにそのクオリティを実現するのはハードルが高いので、下記のような簡易的な方法を採用するのがよいのかなと思っています。
DB上にあいまい検索用のテーブルを作成する
テーブル名はなんでもいいです。そして最低限以下の二つのカラムがあれば十分でしょう。もしかしたらsuggestKeywordListだけでも事足りるかもしれません。
1 2 |
originalKeyword: String //オリジナルのキーワード:例)デジタル suggestKeywordList:[String] //オリジナルのキーワードが入力されたときに同時に検索したい単語のリスト:例)ディジタル,デジタル |
検索ロジックを実行する前にあいまい検索用のテーブル情報のDictionaryを作成しておく
検索の都度、テーブルをSelectすると重いと思うのでページを表示させたタイミングあたりでDictionary形式の対応表を作っておきましょう
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// サジェスト用ディクショナリ var fuzzyDictionary = [String: [String]]() // あいまい検索テーブルを初期化しておく let fuzzyQuery:PFQuery = PFQuery(className: FuzzyWord.parseClassName()) fuzzyQuery.cachePolicy = PFCachePolicy.NetworkElseCache fuzzyQuery.findObjectsInBackgroundWithBlock { (objects, error) -> Void in if error == nil { // エラーなし let fuzzyObjects = objects! as! [fuzzyQuery] for fuzzyObject in fuzzyObjects { let keyword = fuzzyObject.originalKeyword let suggestKeywordList = fuzzyObject.suggestKeywordList // ディクショナリに追加 self.fuzzyDictionary[keyword] = suggestKeywordList } } } |
検索の条件設定を行うときにあいまい検索で得た単語リストをOR条件に指定する
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// あいまい検索の条件を追加 var queryList:[PFQuery] = [] for (key, values) in fuzzyDictionary { if key.containsString(mainKeyword) { for value in values { let fuzzyQuery = PFQuery(className: TargetTable.parseClassName()) //*TargetTable->検索対象のテーブル名 fuzzyQuery.whereKey("name", containsString: value) queryList.append(fuzzyQuery) } } } // queryListを使って初期化 let targetQuery = PFQuery.orQueryWithSubqueries(queryList) |
あいまい検索用のマップをツールか何かでメンテナンスできるようにしておくとどんどん検索精度を上げていくことができますね。思ったより簡単に実装できると思うのでどうぞお試しあれ。