スニペット (抜粋) はインデックスされたソース・テキストの断片で、全文検索の条件に従ってハイライトされた言葉を含むものです。
Sphinx はスニペットを構築する強力なメカニズムを内蔵しています。
しかしながら、Sphinx はオリジナルのインデックスされたテキストを保存しないため、クエリ結果に含まれる行に対するスニペットは、独立した別のクエリによって構築されなければなりません。
そのようなクエリを yii\sphinx\Command::callSnippets()
によって実行することが出来ます。
$sql = "SELECT * FROM idx_item WHERE MATCH('about')";
$rows = Yii::$app->sphinx->createCommand($sql)->queryAll();
$rowSnippetSources = [];
foreach ($rows as $row) {
$rowSnippetSources[] = file_get_contents('/path/to/index/files/' . $row['id'] . '.txt');
}
$snippets = Yii::$app->sphinx->createCommand($sql)->callSnippets('idx_item', $rowSnippetSources, 'about');
このワークフローは、yii\sphinx\Query::snippetCallback() を使って、単純化することが出来ます。 これは、クエリ結果の行の配列を引数として取り、 入力された行の順序にしたがってスニペットのソース文字列の配列を返す PHP コールバックです。 例えば、
use yii\sphinx\Query;
$query = new Query();
$rows = $query->from('idx_item')
->match($_POST['search'])
->snippetCallback(function ($rows) {
$result = [];
foreach ($rows as $row) {
$result[] = file_get_contents('/path/to/index/files/' . $row['id'] . '.txt');
}
return $result;
})
->all();
foreach ($rows as $row) {
echo $row['snippet'];
}
アクティブレコードを使う場合は、yii\sphinx\ActiveQuery::snippetByModel() を使ってスニペットを構築することが出来ます。
このメソッドは、検索結果であるモデルの getSnippetSource()
メソッドを呼ぶことによって、各行ごとにスニペットのソースを取得します。
必要なことは、あなたのアクティブレコード・クラスにおいて、正しい値を返すように getSnippetSource()
メソッドを実装することだけです。
use yii\sphinx\ActiveRecord;
class Article extends ActiveRecord
{
public function getSnippetSource()
{
return file_get_contents('/path/to/source/files/' . $this->id . '.txt');
}
}
$articles = Article::find()->snippetByModel()->all();
foreach ($articles as $article) {
echo $article->snippet;
}