groonga-dev ML 各位 お世話になります。内山と申します。 今、ドキュメント http://mroonga.org/ja/docs/reference/full_text_search/scoring.html の「IN NATURAL LANGUAGE MODEにおける検索スコアの算出方法」 を読んでいました。 わたくしは、Moovle (https://www.moovle.org/ ) という映像の字幕を全文検索して頭出し再生できるサイトを運営しています。 映像は YouTube 映像です。検索スコアはYouTube での視聴回数でスコアリング しています。 視聴回数でスコアリングした結果ですと、その検索語を含む 一般的に視聴されている映像がピックアップされます。これは、 これで悪いわけではないのですが、検索を実行した人は、字幕に検索語を より多く含む映像が重要だと感じる人も多いと思います。その観点から 検索SQL を moovle=# EXPLAIN ( analyze, buffers ) with v AS ( SELECT id, content FROM subtitled WHERE content &@~ 'algorithm' ORDER BY ( (char_length( array_to_string( content, '' ) ) - char_length( replace( array_to_string( content, '' ), 'algorithm', '' )) ) / char_length( 'algorithm' ) ) DESC OFFSET 0 LIMIT 100 ) SELECT id, array_to_json( v.content ) FROM v; QUERY PLAN ---------------------------------------------------------------------------- ---- ---------------------------------------------------------------------------- ---- -------------------------------------- CTE Scan on v (cost=39707.71..39709.96 rows=100 width=40) (actual time=5573.316..5605.910 rows=100 loops=1) Buffers: shared hit=125314 CTE v -> Limit (cost=39707.46..39707.71 rows=100 width=373) (actual time=5572.985..5573.011 rows=100 loops=1) Buffers: shared hit=124579 -> Sort (cost=39707.46..39798.16 rows=36282 width=373) (actual time=5572.982..5573.000 rows=100 loops=1) Sort Key: (((char_length(array_to_string(subtitled.content, '': :text)) - char_length(replace(array_to_string(subtitled.content, ''::text), 'alg orithm'::text, ''::text))) / 9)) DESC Sort Method: top-N heapsort Memory: 32kB Buffers: shared hit=124579 -> Index Scan using subtitled_pgroonga_content_idx on subtitled (cost=0.00..38320.78 rows=36282 width=373) (actual time=13.439..5569.510 rows=10371 loops=1) Index Cond: (content &@~ 'algorithm'::text) Buffers: shared hit=124579 Planning time: 0.925 ms Execution time: 5606.281 ms (14 行) としてみると、検索エンジンでは致命的な 5 秒かかってしまいます。 ここで、ORDER BY 句では、PostgreSQL の関数を使って検索語 algorithm の出現回数を計算しています。 この検索 SQL をYouTube の ViewCount (視聴回数)とすると、 EXPLAIN ( analyze, buffers ) with v AS ( SELECT id, content FROM subtitled WHERE content &@~ 'algorithm' ORDER BY vc DESC OFFSET 0 LIMIT 100 ) SELECT id, array_to_json( v.content ) FROM v; QUERY PLAN ---------------------------------------------------------------------------- ---- ---------------------------------------------------------------------------- ---- ------------- CTE Scan on v (cost=39072.77..39075.02 rows=100 width=40) (actual time=25.831..42.639 rows=100 loops=1) Buffers: shared hit=10152 CTE v -> Limit (cost=39072.52..39072.77 rows=100 width=377) (actual time=25.658..25.686 rows=100 loops=1) Buffers: shared hit=9642 -> Sort (cost=39072.52..39163.23 rows=36282 width=377) (actual time=25.656..25.668 rows=100 loops=1) Sort Key: subtitled.vc DESC Sort Method: top-N heapsort Memory: 34kB Buffers: shared hit=9642 -> Index Scan using subtitled_pgroonga_content_idx on subtitled (cost=0.00..37685.85 rows=36282 width=377) (actual time=8.118..23.379 rows=10371 loops=1) Index Cond: (content &@~ 'algorithm'::text) Buffers: shared hit=9639 Planning time: 0.675 ms Execution time: 43.070 ms (14 行) と0.043 秒になります。 PGroonga でも、全文検索する文章に依存したスコアリング方法は ないでしょうか。ただし、content 列は text 型の配列です。 ご教示のほどよろしくお願いいたします。