検索エンジン機能

検索エンジン機能 #

HottyDBの特徴的機能である検索エンジン機能を紹介します。 転置インデックスによる文書の全文検索や機械学習ランキング(MLR)をSQL LIKEなコマンドで実現する方法を解説します。

全文検索 #

全文検索とは、複数の文書から特定の文字列を含む文書を検索する技術のことを指します。 通常のSQLで全文検索を実現する場合、LIKE句を駆使して部分一致検索をするため、インデックスを利用することができず効率的な検索をすることができません。

HottyDBではSQL LIKEなコマンドで転置インデックスを作成でき、その転置インデックスを利用した全文検索が可能です。 全文検索は通常のSELECT文の中で利用することができます。

このセクションでは、HottyDBで転置インデックスによる全文検索を実現する手順を説明します。

前提 #

前提として、idtitleフィールドを持ったarticleテーブルが作成されているとします(例として用います)。

CREATE TABLE article (id INT, title VARCHAR(30))

転置インデックス作成 #

そのarticleテーブルのtitleフィールドにs1という名前の転置インデックスを作成する場合のコマンドがこちらです。

CREATE SEARCH INDEX s1 ON article (title)

titleフィールドは文字列フィールドである必要があります

SELECT文の中で全文検索 #

title機械学習という文字列を含む記事を全文検索する場合、下記のようなSELECT文になります。

SELECT id, title, _similarity
FROM SEARCH(article, title, '機械学習') 
ORDER BY _similarity DESC

このようにHottyDBの全文検索では、SEARCHメソッドという特殊なメソッドを使います。

  • SEARCHメソッドの引数
    • 第一引数: 検索対象テーブル名
    • 第二引数: 検索対象フィールド名
    • 第三引数: 検索クエリ文字列

SEARCHメソッドは、第三引数の検索クエリを含むレコードを、指定したテーブルから検索するメソッドです。 SEARCHメソッドの出力は通常のテーブルと同じようにSELECT文のFROM句で扱うことができます。 SEARCHメソッドの出力には、元のarticleテーブルのフィールドに加えて、_similarityという検索マッチ度を表すフィールドも追加されます。

例のようにORDER BY _similarity DESCとすることで、マッチ度順に検索結果を並び替えることができます。

機械学習ランキング(MLR) #

実用的な検索サービスでは、単純にマッチ度だけで検索結果をランキングしていません。 アイテムの人気度など、さまざまな特徴量を組み合わせて機械学習によるランキング学習をしていることが多いです。 このセクションでは、HottyDBを使って機械学習ランキングの学習や推論を実行する手順を説明します。

前提 #

まず、前提として、以下のようにid, title, likesという3つのフィールドを持つarticleテーブルが作成されているとします。 likesとは、その記事の人気度を表す指標で「いいねされた数」と捉えてください。

CREATE TABLE article (id INT, title VARCHAR(30), likes INT)

このarticleテーブルのtitleフィールドにs1という転置インデックスが作成されているとします。

CREATE SEARCH INDEX s1 ON article (title)

MLRテンプレートの作成 #

機械学習ランキングの最初の準備として、MLRテンプレートと呼ばれるSELECT文のテンプレートを作成します。

CREATE MLR_TEMPLATEの構文 #

CREATE MLR_TEMPLATE `テンプレート名` 
KEY(`アイテムIDとなるフィールド名`)
`SELECT文`

CREATE MLR_TEMPLATEの例文 #

CREATE MLR_TEMPLATE t1 
KEY(id)
SELECT id, title, likes, _similarity
FROM SEARCH(article, title, ?)

解説 #

  • SELECT文
    • 機械学習ランキングを実行する対象のテーブルデータを作成するSELECT文
    • SELECTフィールドには、アイテムIDと機械学習に使う特徴量を含める必要があります
    • SELECT文には ? のようにPreparedStatementを利用することができ、 検索リクエストの度に変化する検索クエリやより細かな絞り込み条件などを記述することができます
  • アイテムIDとなるフィールド名
    • 後の工程で、検索結果のうちどのアイテムがクリックされたのかといった情報をHottyDBに伝える必要があります
    • その時にアイテムIDとして使うフィールド名をここで指定します
    • アイテムIDとなるフィールドはINT型でも文字列型でも問題ありません

MLRモデルの作成 #

続いて、先ほど作成したMLRテンプレートを指定し、MLRモデルを作成します。 MLRモデルでは、MLRテンプレートの出力フィールドのうち、特徴量として使うフィールド名を指定します。 文字列型のフィールドを指定した場合は、自動的にカテゴリ型の特徴量として扱われます。

CREATE MLR_MODELの構文 #

CREATE MLR_MODEL `モデル名` 
WITH `テンプレート名` (`特徴量となるフィールド名`[, ...])

CREATE MLR_MODELの例文 #

CREATE MLR_MODEL m1 WITH t1 (likes, _similarity)

機械学習ランキングに必要な準備はここまでで、次の項からはいよいよMLRモデルによる推論と学習を行う方法を解説します。

機械学習ランキングの推論 #

SELECT文の中で機械学習ランキングを行うために、MLRメソッドを使います。 MLRメソッドは、MLRテンプレートで作成したSELECT文の出力を機械学習ランキングにより並び替えた結果をテーブルデータで返します。 MLRテンプレートがPreparedStatementの変数?を持つ場合、MLRメソッドでその変数に値を入れる必要があります。

MLRメソッドの構文 #

MLR(`モデル名`, `?の値1`, `?の値2`, ...)

MLRメソッドを使ったSELECT例文 #

SELECT 
  id,
  title,  
  likes,
  _similarity,
  _request_id, 
  _key_id, 
  _score
FROM MLR(m1, '機械学習')

またMLRメソッドは、MLRテンプレートで指定した出力フィールドとは別に、_request_id, _key_id, _scoreの3つのフィールドが追加で出力されます。

  • _request_id
    • 検索リクエストを一意に特定するID
    • 学習データを送信する際に利用
  • _key_id
    • 検索結果内でアイテムを一意に特定するID
    • MLRテンプレートでKEYに指定したフィールドの値を返す
    • 学習データを送信する際に利用
  • _score
    • アイテムの機械学習ランキングにおけるスコア

機械学習ランキングの学習 #

機械学習ランキングの学習では、検索結果一覧の中でクリックされたアイテムとそうでないアイテムの違いを学習する必要があります(ペアワイズ学習)。 そのため、HottyDBへはどの検索リクエストにおいて、どのアイテムがクリックされたのかを伝える必要があります。

そのためのコマンドがINSERT MLR_POSITIVE命令です。

INSERT MLR_POSITIVEの構文 #

INSERT MLR_POSITIVE(`モデル名`, `リクエストID`, `正解アイテムID`)
  • リクエストID
    • 推論時のMLRメソッドの出力_request_idの値
  • 正解アイテムID
    • 推論時のMLRメソッドの出力_key_idの値(クリックされたアイテムの)

INSERT MLR_POSITIVEの例文 #

リクエストID=1の検索リクエストにおいて、アイテムID=4 がクリックされた場合のコマンド例

INSERT MLR_POSITIVE(m1, 1, 4)

上記のように機械学習ランキングの推論と学習を繰り返すことでMLRモデルの学習は進み、より良いランキングモデルへと最適化されていきます。 学習はオンライン学習(SGD)で行われるので、INSERT MLR_POSITIVE命令が呼ばれれば即座にモデルパラメータは更新されます。

将来的に学習ロジックはプラグイン化し、より高度な学習ロジックも実現できるようにしたいと考えています

サンプルコード #

以上のコマンドを実際に使ってみたJavaのサンプルコードはこちらです。

>> 検索エンジン機能のサンプルコード #