コンテンツにスキップ

Pythonのluqumでクエリ文字列を解析する

[質問]

Pythonのluqumを利用して、検索クエリ文字列 "(A OR B) AND C" をパースし、その構文木を表示するプログラムを作ってください。

[回答] Grok

以下は、Pythonの luqum ライブラリを使って検索クエリ文字列 "(A OR B) AND C" をパースし、構文木(抽象構文木)を整形して表示するプログラムです。

必要なインストール

まず、以下のコマンドでライブラリをインストールしてください:

pip install luqum

プログラムコード

from luqum.parser import parser
from luqum.tree import (
    AndOperation, OrOperation, Group, Word, Phrase, Regex, Range, Boost, Proximity, Fuzzy
)

def print_tree(node, indent: int = 0):
    """構文木を再帰的に整形して表示する関数"""
    prefix = "  " * indent

    # ノードの種類に応じた表示
    if isinstance(node, Group):
        print(f"{prefix}Group(")
        for child in node.children:
            print_tree(child, indent + 1)
        print(f"{prefix})")
    elif isinstance(node, AndOperation):
        print(f"{prefix}AND(")
        for child in node.children:
            print_tree(child, indent + 1)
        print(f"{prefix})")
    elif isinstance(node, OrOperation):
        print(f"{prefix}OR(")
        for child in node.children:
            print_tree(child, indent + 1)
        print(f"{prefix})")
    elif isinstance(node, (Word, Phrase)):
        print(f"{prefix}{type(node).__name__}: '{node.value}'")
    elif isinstance(node, (Boost, Proximity, Fuzzy)):
        print(f"{prefix}{type(node).__name__}({node.value})")
    elif isinstance(node, Range):
        print(f"{prefix}Range: {node}")
    elif isinstance(node, Regex):
        print(f"{prefix}Regex: {node.value}")
    else:
        print(f"{prefix}{type(node).__name__}: {node}")

# メイン処理
def main():
    query = "(A OR B) AND C"
    print(f"元のクエリ: {query}\n")

    # パース実行
    tree = parser.parse(query)

    print("=== 構文木 ===")
    print_tree(tree)

    # より詳細なデバッグ情報も出力したい場合は以下を有効化
    # print("\n=== 生のツリーオブジェクト ===")
    # print(repr(tree))

if __name__ == "__main__":
    main()

実行結果の例

上記のプログラムを実行すると、以下のような出力が得られます:

元のクエリ: (A OR B) AND C

=== 構文木 ===
AND(
  Group(
    OR(
      Word: 'A'
      Word: 'B'
    )
  )
  Word: 'C'
)

解説

  • parser.parse(query) でクエリ文字列を解析し、構文木(luqum.tree のオブジェクト)を作成します。
  • print_tree() 関数は再帰的にノードを走査し、AND/OR/Group/Word などの構造をわかりやすく表示します。
  • より複雑なクエリ(例: "hello world" OR (title:python^2 AND date:[2020-01-01 TO 2025-12-31]))にも対応しています。

必要に応じて、print_tree() 関数をさらに拡張して Boost^2)や Proximity~3)、Range などの要素も詳細に表示できます。

このプログラムをベースに、検索エンジン(Elasticsearch, Solrなど)のクエリ解析ツールとして活用してください!