Movatterモバイル変換


[0]ホーム

URL:


V
Sign inSubscribe
2 min read DuckDB

DuckDB で日本語全文検索

DuckDB-VSSPLaMo-Embedding-1B を利用することで、ベクトル検索を実現できますが、DuckDB-FTS (Full-Text Search) と形態素解析ライブラリであるLindera を組み合わせて日本語全文検索を実現できます。

DuckDB-FTS + Lindera

DuckDB の全文検索拡張は日本語には対応していないないのですが、スペース区切りでトークン化することで、日本語の全文検索を利用する事が出来ます。トークン化には Meilisearch にも利用されている信頼と安心の Lindera を利用することにしました。


今回この参考コードを Lindera の作者であり検索の専門家でもあるMinoru OSUKAにレビューいただきました。本当にありがとうございます。

以下は参考コードです。

[project]name = "duckdb-fts-lindera"version = "0.1.0"readme = "README.md"requires-python = ">=3.12"dependencies = [    "duckdb>=1.2.2",    "lindera-py>=0.41.0",]
# SPDX-License-Identifier: Apache-2.0import duckdbfrom lindera_py import Segmenter, Tokenizer, load_dictionarydictionary = load_dictionary("ipadic")segmenter = Segmenter("normal", dictionary)tokenizer = Tokenizer(segmenter)def ja_tokens(text: str) -> str:    return " ".join(t.text for t in tokenizer.tokenize(text))def main():    conn = duckdb.connect()    conn.install_extension("fts")    conn.load_extension("fts")    conn.sql("CREATE SEQUENCE IF NOT EXISTS id_sequence START 1;")    conn.sql("""    CREATE TABLE sora_doc (        id INTEGER DEFAULT nextval('id_sequence') PRIMARY KEY,        content VARCHAR,          content_t VARCHAR    );    """)    # https://sora-doc.shiguredo.jp/ より引用    docs = [        "例えば 3 ノードのクラスターがある場合、 すでに接続しているクライアントがいるノードとは異なるノードにクライアントが接続した場合、Sora はその異なるノードにすでに接続しているクライアントの音声や映像、データをリレーします。",        "StartRecording API やセッションウェブフックの戻り値で指定できる録画メタデータについてはセンシティブなデータとして扱っていません。これは録画ファイル出力時の録画メタデータファイルに含まれ、映像合成時に利用する事を想定しているためです。",        "WebSocket は TCP ベースのため Head of Line Blocking が存在し、不安定な回線などでパケットが詰まってしまうことがあります。 DataChannel は WebSocket とは異なり、パケットを並列でやりとりできるため、不安定な回線などでもパケットが詰まることが少なくなります。 シグナリングを WebSocket 経由から DataChannel 経由へ切り替える機能を提供することでより安定した接続が維持できます。",    ]    for doc in docs:        conn.execute(            "INSERT INTO sora_doc (content, content_t) VALUES (?, ?)",            [                doc,                ja_tokens(doc),            ],        )    query = "センシティブデータについて教えてください"    print("query:", query)    conn.sql("""    PRAGMA create_fts_index(        'sora_doc',        'id',        'content_t',        stemmer = 'none',        stopwords = 'none',        ignore = '',        lower = false,        strip_accents = false    );    """)    q_tokens = ja_tokens(query)    rows = conn.sql(f"""        SELECT id, fts_main_sora_doc.match_bm25(id, '{q_tokens}') AS score, content        FROM sora_doc        WHERE score IS NOT NULL        ORDER BY score DESC    """).fetchall()    for row in rows:        print(f"ID: {row[0]}, Score: {row[1]}, Content: {row[2]}")if __name__ == "__main__":    main()    # query: センシティブデータについて教えてください    # ID: 2, Score: 4.536910447182791, Content: StartRecording API やセッションウェブフックの戻り値で指定できる録画メタデータについてはセンシティブなデータとして扱っていません。これは録画ファイル出力時の録画メタデータファイルに含まれ、映像合成時に利用する事を想定しているためです。    # ID: 1, Score: 1.754047940301512, Content: 例えば 3 ノードのクラスターがある場合、 すでに接続しているクライアントがいるノードとは異なるノードにクライアントが接続した場合、Sora はその異なるノードにすでに接続しているクライアントの音声や映像、データをリレーします。    # ID: 3, Score: 0.8606840213455622, Content: WebSocket は TCP ベースのため Head of Line Blocking が存在し、不安定な回線などでパケットが詰まってしまうことがあります。 DataChannel は WebSocket とは異なり、パケットを並列でやりとりできるため、不安定な回線などでもパケットが詰まることが少なくなります。 シグナリングを WebSocket 経由から DataChannel 経由へ切り替える機能を提供することでより安定した接続が維持できます。

DuckDB-FTS と Lindera を組み合わせることで簡単に日本語全文検索を利用する事ができます、是非試してみてください。

You might also like...

28
4月

ブラウザでオフライン日本語インスタント全文検索を実現する

1 min read
26
4月

DuckDB でハイブリッド検索

4 min read
18
4月

オレオレ RAG をさくっと作る

2 min read
09
4月

製品ドキュメントは読むのではなく質問する時代

2 min read
15
3月

DuckDB UI 使う時は MotherDuck にサインインして FixIt を使おう

1 min read

[8]ページ先頭

©2009-2025 Movatter.jp