Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Goで作る全文検索エンジンライブラリ

Kanji Yomoda
December 02, 2022

 Goで作る全文検索エンジンライブラリ

mercari.go #20で発表したスライドです。
https://mercari.connpass.com/event/266215/

下記、スライド内で紹介した全文検索ライブラリのリポジトリになります。
https://github.com/k-yomo/ostrich

Kanji Yomoda

December 02, 2022
Tweet

More Decks by Kanji Yomoda

Other Decks in Programming

Transcript

  1. Goで作る全文検索エンジンライブラリ Kanji Yomoda (@k-yomo) Dec 2022

  2. Confidential & Proprietary 2021 自己紹介 四方田 貫児 (Kanji Yomoda) Mercari

    [email protected] - ML/Search team Backend engineer
  3. Confidential & Proprietary 2021 アジェンダ • Goの全文検索ライブラリ • 自作全文検索ライブラリ ◦

    概要 ◦ 全文検索ライブラリの挙動 & どうGoを活用しているか
  4. Confidential & Proprietary 2021 全文検索ライブラリ 全文検索ライブラリとは... 検索エンジンの中で使われているコアなライブラリ 検索エンジン 全文検索ライブラリ

  5. Confidential & Proprietary 2021 Goの全文検索ライブラリ Bluge Bleve Riot Couchbase発、スター数最多、TF-IDF Blugeのメンテナの人が新たに開発、

    Grafanaで使われている 現在Public Archive
  6. Confidential & Proprietary 2021 Goの全文検索ライブラリ

  7. Confidential & Proprietary 2021 自作全文検索ライブラリ - Ostrich

  8. Confidential & Proprietary 2021 実装されている機能 • Full-text search for multi

    fields • Configurable analyzer • Concurrent indexing in batch • Segment merge with LogMergePolicy • Mmap directory • Natural query language (e.g. "(go OR golang) AND (search or fts)") • Concurrent search • TF-IDF scoring (BM25も実装予定)
  9. Confidential & Proprietary 2021 未実装な機能 • Document deletion • Integer,

    Date, Geo point fields • BM25 scoring • Phrase search • Aggregation • Efficient data structure, algorithm and compression • その他諸々
  10. Confidential & Proprietary 2021 Indexing Document Per field inverted index

    Serialization Analyze(char_filter, tokenize, token_filter) Batch queue Segment Segment Segment Segment
  11. Confidential & Proprietary 2021 Document Document Per field inverted index

    Serialization Analyze(char_filter, tokenize, token_filter) Batch queue Segment Segment Segment Segment
  12. Confidential & Proprietary 2021 Document

  13. Confidential & Proprietary 2021 Document

  14. Confidential & Proprietary 2021 Batch queue Document Per field inverted

    index Serialization Analyze(char_filter, tokenize, token_filter) Batch queue Segment Segment Segment Segment
  15. Confidential & Proprietary 2021 Batch queue google.golang.org/api/support/bundler • GCPのPub/SubのPublishで使われているバッチ処理のライブラリ •

    Goroutineの数やバッチ化する閾値(count, bytes)を指定してバッチ化
  16. Confidential & Proprietary 2021 Batch queue

  17. Confidential & Proprietary 2021 Indexing Document Per field inverted index

    Serialization Analyze(char_filter, tokenize, token_filter) Batch queue Segment Segment Segment Segment
  18. Confidential & Proprietary 2021 転置index Doc0 Name ナイキ 白 ナイキT

    シャツ Description … … メンズ ナイキ Tシャツ 白 name description Doc1 Name ナイキ メンズ Tシャ ツ Description … [1] [0, 1] [0, 1] [0] Postings list [0, 1] [2, 1] [1, 1] [1, 0] Frequency list
  19. Confidential & Proprietary 2021 Serialization Document Per field inverted index

    Serialization Analyze(char_filter, tokenize, token_filter) Batch queue Segment Segment Segment Segment
  20. Confidential & Proprietary 2021 Serialization メンズ ナイキ Tシャツ 白 name

    [1] [0, 1] [0, 1] Postings list [0, 1] [2, 1] [1, 1] Frequency list [0] [1, 0] gob/encoder Postings File Footer (固定長) - Postings listのバイト数 - Frequency listのバイト数 Postings list (可変長) Frequency list (可変長) binary.LittleEndian.PutUint64() Footer (固定長) - Postings listのバイト数 - Frequency listのバイト数 Postings list (可変長) Frequency list (可変長) メンズ => 0:203 ナイキ => 204:502 … Term dictionary => 語句と対応するポス ティングリストのrangeのマッピング (postings + frequency + footer) Term dictionary File
  21. Confidential & Proprietary 2021 Segment Postings File Term dictionary File

    name: { “メンズ”: => 0:203, “ナイキ”: => 204:502, … } description: { “ナイキ”: => 1004:1209, … } Footer Postings list Frequency list Postings list Frequency list Footer Footer Postings list Frequency list Postings list Frequency list Footer ・・・
  22. Confidential & Proprietary 2021 Search

  23. Confidential & Proprietary 2021 Search Query Collect segments Result Analyzer

    Parser
  24. Confidential & Proprietary 2021 Collector • セグメントからクエリにマッチするドキュメントを取ってくる a. 語句とポスティングリストの対応を取得 (boy

    => 0:203) b. ポスティングリストをファイルから読み込む c. Footerを読み込む(last 16 bytes) (postings => 0:94, frequency => 95:187) d. ポスティングリスト内のドキュメントを取得・スコアリング • 各セグメントの結果をマージ Postings File Footer (固定長) - Postings listのバイト数 - Frequency listのバイト数 Postings list (可変長) Frequency list (可変長) Footer (固定長) - Postings listのバイト数 - Frequency listのバイト数 Postings list (可変長) Frequency list (可変長) メンズ => 0:203 ナイキ => 204:502 … Term dictionary File
  25. Confidential & Proprietary 2021 Collector with generics

  26. Confidential & Proprietary 2021 Collector with generics ⇦ 型安全

  27. Confidential & Proprietary 2021 今後の改善点 • 未実装の機能の追加 (ドキュメントの削除, フィールドタイプの追加, aggregation,

    etc…) • パフォーマンスチューニング (辞書をFSTに変更、セグメントのブロック化・圧縮、WAND, etc…) • テストのカバレッジ
  28. Confidential & Proprietary 2021 まとめ • Goの検索エンジンライブラリを紹介 • 自作全文検索ライブラリでは下記のようなGoの機能・ライブラリを活用 ◦

    Goroutine(バッチindexing) ◦ gob/encoder、binaryパッケージ(シリアライズ) ◦ Generics(検索) • Ostrichは今後もコツコツ改善予定
  29. Confidential & Proprietary 2021 Thanks!