Pythonのluqumでクエリ文字列を解析する
[質問]
Pythonのluqumを利用して、検索クエリ文字列 "(A OR B) AND C" をパースし、その構文木を表示するプログラムを作ってください。
[回答] Grok
以下は、Pythonの luqum ライブラリを使って検索クエリ文字列 "(A OR B) AND C" をパースし、構文木(抽象構文木)を整形して表示するプログラムです。
必要なインストール
まず、以下のコマンドでライブラリをインストールしてください:
プログラムコード
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()
実行結果の例
上記のプログラムを実行すると、以下のような出力が得られます:
解説
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など)のクエリ解析ツールとして活用してください!