Alfanous - Quranic Search Engine について
Alfanous は『コーラン』を対象とした検索エンジン API で、Python ライブラリまたは RESTful Web サービスとして利用できます。アラビア語テキスト、Buckwalter 転写、ブール演算やフィールド指定の検索、あいまい検索に対応し、節の検索ツールを開発する開発者向けです。
主な機能
- 01アラビア語の節に対する簡易検索と高度な検索
- 02ブール演算、ワイルドカード、フィールド指定の構文
- 03編集距離を設定できるあいまい検索
- 04語幹、語彙素、語根レベルの派生検索
- 05ファセット集計と複数の出力ビュー
活用シーン
- 01アラビア語コーラン検索アプリケーションの開発
- 02語根や語形変化による節の検索
- 03Web サービスを通じた節検索機能の提供
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
ツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
Alfanous API
Alfanous は、聖クルアーンを対象としたシンプルな検索と高度な検索機能を提供する、クルアーン検索エンジン API です。開発者は、Buckwalter の音訳、高度なクエリ構文、豊富なメタデータに対応した、アラビア語のクルアーン本文を検索するアプリケーションを構築できます。
機能
- 強力な検索:シンプルなクエリや高度なブール論理を使ってクルアーンの節を検索できます
- アラビア語のサポート:アラビア語のテキストと Buckwalter の音訳を完全にサポートします
- 豊富なメタデータ:節の情報、翻訳、朗誦、言語データにアクセスできます
- 柔軟な API:Python ライブラリまたは RESTful ウェブサービスとして利用できます
- ファセット検索:スーラ、ジュズ、トピックなどで検索結果を集計できます
- 複数の出力形式:さまざまなビューやハイライトスタイルで出力をカスタマイズできます
クイックスタート
インストール
pip を使って PyPI からインストールします:
$ pip install alfanous3
基本的な使い方
Python ライブラリ
>>> from alfanous import api
# Simple search for a word
>>> api.search(u"الله")
# Advanced search with options
>>> api.do({"action": "search", "query": u"الله", "page": 1, "perpage": 10})
# Search using Buckwalter transliteration
>>> api.do({"action": "search", "query": u"Allh"})
# Get suggestions
>>> api.do({"action": "suggest", "query": u"الح"})
# Correct a query
>>> api.correct_query(u"الكتاب")
# Get metadata information
>>> api.do({"action": "show", "query": "translations"})
ウェブサービス
公開ウェブサービスも利用できます:
または、独自のウェブサービスをローカルで実行できます(alfanous_webapi を参照してください)。
クイック例
フレーズを検索します:
>>> api.search(u'"الحمد لله"')
ブール検索(AND、OR、NOT):
>>> api.search(u'الصلاة + الزكاة') # AND
>>> api.search(u'الصلاة | الزكاة') # OR
>>> api.search(u'الصلاة - الزكاة') # NOT
フィールドを指定した検索:
>>> api.search(u'سورة:يس') # Search in Sura Yasin
>>> api.search(u'سجدة:نعم') # Search verses with sajda
ワイルドカード検索:
>>> api.search(u'*نبي*') # Words containing "نبي"
ファセット検索(フィールドごとに集計):
>>> api.do({
... "action": "search",
... "query": u"الله",
... "facets": "sura_id,juz"
... })
ドキュメント
API リファレンス
コア関数
api.search(query, **options)- クルアーンの節を検索しますapi.do(params)- すべてのアクション(search、suggest、show、list_values、correct_query)を扱う統合インターフェースですapi.correct_query(query, unit, flags)- クエリのスペルを修正した結果を取得しますapi.get_info(category)- メタデータ情報を取得します
内部の Raw 出力エンジンは、alfanous.api の Engine として公開されています(alfanous からも直接再エクスポートされています)。インデックスのリソースが適切に解放されるよう、コンテキストマネージャーとして使用してください:
from alfanous.api import Engine
# or equivalently:
# from alfanous import Engine
with Engine() as engine:
result = engine.do({"action": "search", "query": u"الله"})
検索パラメーター
action="search" を指定した api.do() の一般的なパラメーター:
query(str):検索クエリ(必須)unit(str):検索単位 — "aya"、"word"、"translation"(既定値:"aya")page(int):ページ番号(既定値:1)perpage(int):1 ページあたりの検索結果数、1~100(既定値:10)sortedby(str):並べ替え順 — "score"、"relevance"、"mushaf"、"tanzil"、"ayalength"(既定値:"score")reverse(bool):並べ替え順を逆にします(既定値:False)view(str):出力ビュー — "minimal"、"normal"、"full"、"statistic"、"linguistic"(既定値:"normal")highlight(str):ハイライトスタイル — "css"、"html"、"bold"、"bbcode"(既定値:"css")script(str):テキストの表記 — "standard" または "uthmani"(既定値:"standard")vocalized(bool):アラビア語の母音記号を含めるかどうか(既定値:True)translation(str):含める翻訳の IDrecitation(str):含める朗誦の ID(1~30、既定値:"1")fuzzy(bool):あいまい検索を有効にします。aya_(完全一致)フィールドとaya(正規化/語幹化)フィールドの両方を検索し、レーベンシュタイン距離による照合も行います(既定値:False)。完全一致検索とあいまい検索 を参照してください。fuzzy_maxdist(int):あいまいな語句照合におけるレーベンシュタイン編集距離の最大値 —1、2、または3(既定値:1。fuzzy=Trueの場合にのみ使用されます)。facets(str):ファセット検索の対象フィールドをカンマ区切りで指定したリストfilter(dict):フィールドの値で検索結果を絞り込みます
パラメーターとオプションの一覧については、詳細なドキュメント を参照してください。
高度な機能
完全一致検索とあいまい検索
Alfanous には、検索対象となるインデックスフィールドを制御する、相互に補完する 2 つの検索モードがあります。
厳密な検索(デフォルト — fuzzy=False)
あいまい検索がオフ(デフォルト)の場合、クエリは**aya_**フィールドに対して実行されます。このフィールドには、発音記号(タシュキール)を保持した、完全に母音記号付きのクルアーン本文が格納されています。このモードは、正確で統計的な照合を目的としています。
- クエリ内の発音記号は重要です。
مَلِكِとمَالِكِは異なる単語として扱われます。 - クエリには、ストップワードの除去、同義語の拡張、語幹処理は適用されません。
- 正確なフレーズの一致、再現可能な検索結果数、統計分析が必要な場合に最適です。
# Default exact search — only the vocalized aya_ field is used
>>> api.search(u"الله")
>>> api.search(u"الله", fuzzy=False)
# Phrase match with full diacritics
>>> api.search(u'"الْحَمْدُ لِلَّهِ"')
あいまい検索(fuzzy=True)
あいまい検索がオンの場合、クエリは**aya_フィールド(完全一致)とaya**フィールド(幅広く柔軟な検索向けに構築された別個のインデックス)の両方に対して実行されます。インデックス作成時に、ayaフィールドはより充実した処理パイプラインを通じて処理されます。
- 正規化 — 字形、タトウィール、ハムザの異形、および一般的なスペルミスを統一します。
- ストップワードの除去 — 高頻度の機能語(例:مِنْ، فِي، مَا)を除外し、検索結果の関連性が薄まらないようにします。
- 同義語の拡張 — 各トークンは同義語とともに格納されるため、ある単語で検索すると、同等の単語も自動的に一致します。
- アラビア語の語幹処理 — Snowball Arabic stemmer(
pystemmer経由)を使って単語を語幹に縮約するため、同じ語根を持つ異なる形態の単語が一致します。
検索時にクエリ文字列へ負荷の高い処理は行いません。言語的な拡充はすべてインデックス内で行われます。
さらに、クエリ内の各アラビア語の語句について、aya_acフィールド(母音記号なし、語幹処理なし)に対してレーベンシュタイン距離検索が行われます。これにより、fuzzy_maxdistで制御される設定可能な編集距離の範囲内で、スペルの異形や誤字を検出できます。
# Fuzzy search — aya_ (exact) + aya (normalised/stemmed) + Levenshtein distance on aya_ac
>>> api.search(u"الكتاب", fuzzy=True)
# Increase edit distance to 2 to tolerate more spelling variation
>>> api.search(u"الكتاب", fuzzy=True, fuzzy_maxdist=2)
# Via the unified interface
>>> api.do({
... "action": "search",
... "query": u"مؤمن",
... "fuzzy": True,
... "fuzzy_maxdist": 1,
... "page": 1,
... "perpage": 10
... })
fuzzy_maxdist | 動作 |
|---|---|
1(デフォルト) | 1文字の挿入、削除、置換を検出します |
2 | より広い許容範囲です。長い単語やノイズの多い入力に便利です |
3 | サポートされる最大値です。再現率が大幅に高くなるため、注意して使用してください |
あいまい検索モードは、特に次の場合に便利です。
- ユーザーが単語の正確な母音記号付き表記を知らない場合。
- 形態的に関連する単語を同じ検索結果に表示したい場合(例:كتبで検索すると、كتاب、كاتب、مكتوبも表示されます)。
- 明示的な OR クエリを記述せずに、同義語を考慮した検索を行いたい場合。
注: 語幹処理を有効にするには、
pystemmerをインストールする必要があります(pip install pystemmer)。パッケージがない場合、語幹処理フィルターは警告なしで何もしない状態になり、正規化とストップワードの除去は引き続き有効です。
フィールド値の一覧表示
list_valuesは、指定したフィールドのインデックス済みの一意な値をすべて返します。クエリを作成する前に、利用可能な翻訳識別子、品詞タグ、語根など、検索可能なフィールドの語彙全体を調べるために使用します。
# Get all unique root values in the index
>>> api.do({"action": "list_values", "field": "root"})
# Returns: {"list_values": {"field": "root", "values": [...], "count": N}}
# Discover all indexed translation IDs
>>> api.do({"action": "list_values", "field": "trans_id"})
# Discover all part-of-speech categories for word search
>>> api.do({"action": "list_values", "field": "pos"})
# Retrieve all indexed lemmas on demand (replaces the former show/lemmas)
>>> api.do({"action": "list_values", "field": "lemma"})
パラメーター:
field(str):一意な値を取得するインデックス済みフィールドの名前(必須)。
戻り値:
list_valuesキーを含む辞書で、以下の内容が格納されます。
field— 要求されたフィールド名。values— 空でないインデックス済みの一意な値を並べ替えたリスト。count—valuesリストの長さ。
クエリの修正
correct_query() は Whoosh の組み込みスペルチェッカーを使用して、クエリ内の各語をインデックスの語彙と照合し、未知の語を最も近い既知の候補に置き換えます。クエリがすでに有効な場合(すべての語がインデックスに含まれている場合)、応答の corrected の値は元の入力と同一です。
# Correct a query via the dedicated function
>>> api.correct_query(u"الكتاب")
# Returns:
# {"correct_query": {"original": "الكتاب", "corrected": "الكتاب"}, "error": ...}
# Correct a misspelled / out-of-vocabulary term
>>> api.correct_query(u"الكتب")
# Returns:
# {"correct_query": {"original": "الكتب", "corrected": "الكتاب"}, "error": ...}
# Via the unified interface
>>> api.do({"action": "correct_query", "query": u"الكتب", "unit": "aya"})
パラメーター:
query(str):修正する未処理のクエリ文字列です(必須)。unit(str):検索単位です。現在は"aya"のみがサポートされており、その他の単位ではNoneが返されます(デフォルト:"aya")。flags(dict):追加のフラグを指定する省略可能な辞書です。
戻り値:
correct_query キーを含む辞書です。内容は次のとおりです。
original— 入力されたクエリ文字列です。corrected— 修正後のクエリ文字列です。修正が不要な場合はoriginalと同一です。
クエリ構文
Alfanous は高度なクエリ構文をサポートしています。
- フレーズ:引用符を使用します -
"الحمد لله" - ブール AND:
+を使用します -الصلاة + الزكاة - ブール OR:
|を使用します -الصلاة | الزكاة - ブール NOT:
-を使用します -الصلاة - الزكاة - ワイルドカード:複数の文字には
*、1 文字には?を使用します -*نبي*、نعم؟ - フィールド指定検索:フィールド名を使用します -
سورة:يس、سجدة:نعم - 範囲:
[X الى Y]を使用します -رقم_السورة:[1 الى 5] - 部分的な発音記号:一部の発音記号を付けて検索します -
آية_:'مَن' - 派生(語幹):
>を使用します ->رحيم(aya_stemを検索します — コーパスから導出された語幹) - 派生(レマ):
>>を使用します ->>رحيم(aya_lemmaを検索します — 同じ語彙素のすべての活用形) - 派生(語根):
>>>を使用します ->>>ملك(aya_rootを検索します — 同じ語根を持つすべての語) - タプル:
{root,type}を使用します -{قول،اسم}
派生レベル検索
derivation_level パラメーターを使用して、形態論的に検索対象をどの程度広げるかを指定します。
| レベル | 値 | インデックスフィールド | 説明 |
|---|---|---|---|
| 0 | "word" | aya | 完全一致のみ(デフォルト) |
| 1 | "stem" | aya_stem | コーパスから導出された語幹 — 同じ形態論的語幹を共有する語 |
| 2 | "lemma" | aya_lemma | コーパスのレマ — 同じ語彙素のすべての活用形 |
| 3 | "root" | aya_root | 三子音語根 — 同じ語根を持つすべての語 |
各派生フィールドはビルド時にあらかじめインデックス化されるため、検索時に展開するのではなく、コンパクトな事前計算済みの表現に対してクエリを実行します。
# Level 0 — exact match
>>> api.do({"action": "search", "query": "رَحِيمٌ"})
# Level 1 — stem (corpus-derived stem)
>>> api.do({"action": "search", "query": "رحيم", "derivation_level": 1})
# Level 2 — all words sharing the same lemma (e.g. all forms of رَحِيمٌ)
>>> api.do({"action": "search", "query": "رحيم", "derivation_level": 2})
# Level 3 — all words from root رحم (رحمة، رحمن، رحيم، يرحم، …)
>>> api.do({"action": "search", "query": "رحيم", "derivation_level": 3})
# String aliases are also accepted
>>> api.do({"action": "search", "query": "كتب", "derivation_level": "root"})
派生構文 >word、>>word、>>>word はそれぞれレベル 1、2、3 に対応し、クエリに直接埋め込めます。
# Stem-level derivation in a query expression
>>> api.do({"action": "search", "query": ">رحيم"})
# Root-level: all words from root ملك
>>> api.do({"action": "search", "query": ">>>ملك"})
# Combined with field filters
>>> api.do({"action": "search", "query": ">>الله AND سورة:الإخلاص"})
単語検索(unit="word")
unit="word" の場合、エンジンは節レベルの親ドキュメントではなく、単語レベルの子ドキュメントを検索します。各単語の子ドキュメントには、品詞、レマ、語幹、語根、語形、性、数、人称、態、法、派生レベルなど、完全な形態論的注釈が付与されています。
# Search all words matching "الله" at word level
>>> api.do({"action": "search", "query": "الله", "unit": "word"})
# Derivation levels also apply to word search:
# Level 1 — search word_stem (corpus-derived stem)
>>> api.do({"action": "search", "query": "رحيم", "unit": "word", "derivation_level": 1})
# Level 2 — search word_lemma (normalized lemma)
>>> api.do({"action": "search", "query": "رحيم", "unit": "word", "derivation_level": 2})
# Level 3 — search root (exact root value, e.g. "رحم")
>>> api.do({"action": "search", "query": "رحم", "unit": "word", "derivation_level": 3})
形態論的フィルタリング(search_by_word_linguistics)
search_by_word_linguistics アクションを使用すると、形態論的特性を任意に組み合わせて単語を絞り込めます。
# Find all nouns from root قول
>>> api.do({
... "action": "search_by_word_linguistics",
... "root": "قول",
... "type": "أسماء" # Arabic POS category name
... })
# Find all active-voice past-tense verbs from root كتب
>>> api.do({
... "action": "search_by_word_linguistics",
... "root": "كتب",
... "pos": "V",
... "voice": "مبني للمعلوم",
... "aspect": "فعل ماضي"
... })
# Find all proper nouns
>>> api.do({
... "action": "search_by_word_linguistics",
... "pos": "PN"
... })
利用可能な形態論的フィルターフィールドには、pos、type、root、lemma、stem、pattern、gender、number、person、voice、mood、state、case、form、aspect、derivation、special、prefix、suffix、segments があります。
ファセット検索では、フィールドごとに検索結果を集計できます。
>>> result = api.do({
... "action": "search",
... "query": u"الله",
... "facets": "sura_id,juz,chapter"
... })
>>> print(result["search"]["facets"])
利用可能なファセットフィールド:
sura_id- スーラ(章)番号(1~114)juz- ジュズ(分冊)番号(1~30)hizb- ヒズブ(節)番号chapter- 主題/章topic- サブトピックsura_type- マッカ啓示/マディーナ啓示の分類
結果のフィルタリング
フィールド値で検索結果を絞り込みます。
>>> api.do({
... "action": "search",
... "query": u"الله",
... "filter": {"sura_id": "2"} # Only from Sura Al-Baqarah
... })
検索フィールド
フィールドを指定した検索で使用できるフィールド:
سورة(sura) - スーラ名رقم_السورة(sura_id) - スーラ番号رقم_الآية(aya_id) - 節番号جزء(juz) - ジュズ番号حزب(hizb) - ヒズブ番号صفحة(page) - ムスハフのページ番号سجدة(sajda) - サジダの有無موضوع(subject) - 主題/テーマفصل(chapter) - 章باب(subtopic) - サブトピックنوع_السورة(sura_type) - スーラの種類(マッカ啓示/マディーナ啓示)
単語レベルのフィールド(unit="word" と併用):
englishstate- 英語での名詞の状態(例:「Definite state」、「Indefinite state」)englishmood- 英語での動詞の法(例:「Indicative mood」、「Subjunctive mood」、「Jussive mood」)
フィールドの一覧は、次を呼び出してください:
>>> api.do({"action": "show", "query": "fields"})
出力ビュー
ビューによって詳細レベルが異なります:
- minimal - 基本的な節のテキストと識別子
- normal - 重要なメタデータを含む節のテキスト
- full - 利用可能なすべての情報
- statistic - 統計情報を含む
- linguistic - 言語分析を含む
例:
>>> api.do({
... "action": "search",
... "query": u"الله",
... "view": "full",
... "word_info": True,
... "aya_theme_info": True
... })
メタデータへのアクセス
「show」アクションを使って、さまざまなメタデータを取得できます:
# Get list of available translations
>>> api.do({"action": "show", "query": "translations"})
# Get list of recitations
>>> api.do({"action": "show", "query": "recitations"})
# Get Sura information
>>> api.do({"action": "show", "query": "surates"})
# Get search fields
>>> api.do({"action": "show", "query": "fields"})
# Get default values
>>> api.do({"action": "show", "query": "defaults"})
注: レンマは
showでは公開されなくなりました。api.do({"action": "list_values", "field": "lemma"})を使って、必要に応じて取得してください。
新しい翻訳の追加
index_translations() を使って、Zekr 互換の追加の .trans.zip 翻訳ファイルをローカル検索インデックスに追加できます。これには alfanous_import パッケージが必要です(リポジトリ内の src/alfanous_import/ に含まれています)。
import alfanous.api as alfanous
# Index all .trans.zip files found in a folder
count = alfanous.index_translations(source="/path/to/translations")
print(f"{count} translation(s) newly indexed")
この関数は次の処理を行います:
source内のすべての*.trans.zipファイルを順に処理します- すでにインデックスにある翻訳はスキップします(冪等性があり、繰り返し安全に呼び出せます)
- 新たにインデックス化された翻訳の件数を返します(
0は新たに追加されたものがないことを示します) configs/translations.jsonを自動的に更新し、新しい翻訳をapi.get_info("translations")ですぐに確認できるようにするとともに、unit="translation"で検索できるようにします
インデックス化した後、新しい翻訳を検索します:
# Search in a newly indexed translation
result = alfanous.search(u"الرحمن", unit="translation", flags={"translation": "en.newt"})
一連の手順については、examples/index_translations_example.py を参照してください。
例
examples/ ディレクトリには、さまざまな機能を説明するスクリプトの例があります:
- facet_search_examples.py - ファセット検索とフィルタリングの例
詳しくは examples/README.md を参照してください。
MCP サーバー
Alfanous には、AI アシスタント(Claude、Copilot など)がクルアーンを直接検索して調べられる MCP(Model Context Protocol) サーバーが含まれています。詳細なリファレンスは alfanous_mcp/README.md を参照してください。
クイックスタート:
$ pip install alfanous3-mcp
$ python -m alfanous_mcp.mcp_server # stdio – works with Claude Desktop
Claude Desktop に接続するには、claude_desktop_config.json に次の内容を追加してください:
{
"mcpServers": {
"alfanous": {
"type": "stdio",
"command": "python",
"args": ["-m", "alfanous_mcp.mcp_server"],
"tools": [
"search_quran",
"search_translations",
"get_quran_info",
"search_quran_by_themes",
"search_quran_by_stats",
"search_quran_by_position",
"suggest_query",
"correct_query",
"search_by_word_linguistics",
"list_field_values"
]
}
}
}
Web インターフェース
Alfanous には、RESTful アクセス用の FastAPI ベースの Web サービスが含まれています。以下については alfanous_webapi/README.md を参照してください:
- インストールとセットアップ
- API エンドポイント
- リクエスト/レスポンスの例
- インタラクティブな API ドキュメント(Swagger UI)
クイックスタート:
$ pip install alfanous3 fastapi uvicorn
$ cd src/
$ uvicorn alfanous_webapi.web_api:app --reload
インタラクティブなドキュメントを表示するには、http://localhost:8000/docs にアクセスしてください。
貢献
貢献を歓迎します!以下については CONTRIBUTING.md を参照してください:
- 開発環境のセットアップ
- ソースからのビルド
- テストの実行
- プルリクエストの提出
- コードスタイルのガイドライン
開発環境のクイックセットアップ:
# Clone the repository
$ git clone https://github.com/Alfanous-team/alfanous.git
$ cd alfanous
# Install dependencies
$ pip install pyparsing whoosh pystemmer pytest
# Build indexes (required for development)
$ make build
# Run tests
$ pytest -vv --rootdir=src/
サポート
- GitHub Issues:https://github.com/Alfanous-team/alfanous/issues
- メーリングリスト:[email protected]
- Web サイト:http://alfanous.org
ライセンス
Alfanous は GNU Lesser General Public License v3 or later(LGPLv3+) の下でライセンスされています。
詳細は LICENSE を参照してください。
クレジット
- 貢献者:AUTHORS.md と THANKS.md を参照してください
このプロジェクトは神聖な宗教文書(聖クルアーン)を扱います。データとコードを尊重して取り扱ってください。
レガシー
レガシー版のAlfanousコードをお探しの場合は、legacy ブランチにあります。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。