Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

Confidential & Proprietary 2021 自己紹介 四方田 貫児 (Kanji Yomoda) Mercari US@Tokyo - ML/Search team Backend engineer

Slide 3

Slide 3 text

Confidential & Proprietary 2021 アジェンダ ● Goの全文検索ライブラリ ● 自作全文検索ライブラリ ○ 概要 ○ 全文検索ライブラリの挙動 & どうGoを活用しているか

Slide 4

Slide 4 text

Confidential & Proprietary 2021 全文検索ライブラリ 全文検索ライブラリとは... 検索エンジンの中で使われているコアなライブラリ 検索エンジン 全文検索ライブラリ

Slide 5

Slide 5 text

Confidential & Proprietary 2021 Goの全文検索ライブラリ Bluge Bleve Riot Couchbase発、スター数最多、TF-IDF Blugeのメンテナの人が新たに開発、 Grafanaで使われている 現在Public Archive

Slide 6

Slide 6 text

Confidential & Proprietary 2021 Goの全文検索ライブラリ

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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も実装予定)

Slide 9

Slide 9 text

Confidential & Proprietary 2021 未実装な機能 ● Document deletion ● Integer, Date, Geo point fields ● BM25 scoring ● Phrase search ● Aggregation ● Efficient data structure, algorithm and compression ● その他諸々

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

Confidential & Proprietary 2021 Document

Slide 13

Slide 13 text

Confidential & Proprietary 2021 Document

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

Confidential & Proprietary 2021 Batch queue google.golang.org/api/support/bundler ● GCPのPub/SubのPublishで使われているバッチ処理のライブラリ ● Goroutineの数やバッチ化する閾値(count, bytes)を指定してバッチ化

Slide 16

Slide 16 text

Confidential & Proprietary 2021 Batch queue

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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 ・・・

Slide 22

Slide 22 text

Confidential & Proprietary 2021 Search

Slide 23

Slide 23 text

Confidential & Proprietary 2021 Search Query Collect segments Result Analyzer Parser

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

Confidential & Proprietary 2021 Collector with generics

Slide 26

Slide 26 text

Confidential & Proprietary 2021 Collector with generics ⇦ 型安全

Slide 27

Slide 27 text

Confidential & Proprietary 2021 今後の改善点 ● 未実装の機能の追加 (ドキュメントの削除, フィールドタイプの追加, aggregation, etc…) ● パフォーマンスチューニング (辞書をFSTに変更、セグメントのブロック化・圧縮、WAND, etc…) ● テストのカバレッジ

Slide 28

Slide 28 text

Confidential & Proprietary 2021 まとめ ● Goの検索エンジンライブラリを紹介 ● 自作全文検索ライブラリでは下記のようなGoの機能・ライブラリを活用 ○ Goroutine(バッチindexing) ○ gob/encoder、binaryパッケージ(シリアライズ) ○ Generics(検索) ● Ostrichは今後もコツコツ改善予定

Slide 29

Slide 29 text

Confidential & Proprietary 2021 Thanks!