Chat
Ask me anything
Ithy Logo

Azure AI Searchを活用したExcelファイル名からのドキュメント検索

指定されたExcelファイル内のファイル名に基づき、Azure AI Searchで関連ドキュメントを検索するPythonプログラムについて解説します。

search-azure-ai-excel-filenames-fgi07igw

Azure AI Searchは、エンタープライズデータをインデックス化し、リッチな検索エクスペリエンスを提供するフルマネージドの検索サービスです。ファイルの内容やメタデータから情報を抽出し、高速かつ関連性の高い検索を可能にします。特に、Azure Blob Storageなどに格納された様々な形式のドキュメントに対して強力な検索機能を提供します。今回のユースケースのように、特定のファイル名やパス、ページ番号といった条件でドキュメントを絞り込む際に非常に有効です。


主要なポイント

  • PythonとAzure AI Search SDKを使用: 提供されたコードスニペットを基に、Pythonのazure-search-documentsライブラリを使用してAzure AI Searchと連携します。
  • Excelファイルからのファイル名抽出: Pandasライブラリを用いてExcelファイル(file_comparison_b_base_merged_optimized.xlsx)の「不一致データ」シートからファイル名リストを取得します。
  • Azure AI Searchでのフィルタリング検索: 抽出したファイル名、そしてfilepathpageフィールドを用いた複合フィルタリングにより、目的のドキュメントを検索します。特にpageが「1」のドキュメントに絞り込みます。

Azure AI Searchの仕組みと関連性

Azure AI Searchは、データソースからドキュメントを取り込み、検索可能なインデックスを構築します。このプロセスには、テキスト抽出、エンティティ認識、キーフレーズ抽出などのスキルセットを適用できます。検索時には、ユーザーからのクエリを受け付け、インデックスに対して全文検索やフィルタリング、ファセット検索などを実行し、関連性の高い結果を返します。

今回のシナリオでは、Azure AI Searchが既にExcelファイルを含む様々なドキュメントをインデックス化していることを前提としています。Excelファイルの内容だけでなく、ファイル名やページ番号といったメタデータもインデックスに含まれていると考えられます。これにより、効率的なフィルタリング検索が可能になります。

Azure AI Searchの主要機能の評価レーダーチャート

上記のレーダーチャートは、Azure AI Searchの主要な機能を相対的に評価したものです。特にフィルタリング機能は、特定の条件に基づいてドキュメントを絞り込む際に非常に強力であり、今回のファイル名やページ番号による検索において重要な役割を果たします。


必要なライブラリのインストール

このプログラムを実行するためには、以下のPythonライブラリが必要です。インストールされていない場合は、pipを使ってインストールしてください。


pip install azure-search-documents azure-identity pandas openpyxl python-dotenv
  • azure-search-documents: Azure AI SearchにアクセスするためのSDKです。
  • azure-identity: Azureサービスへの認証に使用します。
  • pandas: Excelファイルを読み込み、データを操作するために使用します。
  • openpyxl: PandasがExcelファイルを読み込む際に必要となるエンジンです。
  • python-dotenv: .envファイルから環境変数を読み込むために使用します。

Excelファイルからのファイル名抽出

まず、指定されたExcelファイル(file_comparison_b_base_merged_optimized.xlsx)の「不一致データ」シートから、A列に記載されているファイル名のリストを取得します。これにはPandasライブラリが非常に便利です。


import pandas as pd

def extract_filenames_from_excel(excel_filepath, sheet_name="不一致データ", column_name="original_filename"):
    """
    指定されたExcelファイルとシートから、指定された列のファイル名を抽出します。

    Args:
        excel_filepath (str): Excelファイルのパス。
        sheet_name (str): ファイル名を抽出するシートの名前。
        column_name (str): ファイル名が記載されている列の名前。

    Returns:
        list: 抽出されたファイル名のリスト。エラーが発生した場合は空のリスト。
    """
    try:
        df = pd.read_excel(excel_filepath, sheet_name=sheet_name)
        if column_name in df.columns:
            # NaN値を除外してリストとして返す
            filenames = df[column_name].dropna().tolist()
            return filenames
        else:
            print(f"Error: Column '{column_name}' not found in sheet '{sheet_name}'.")
            return []
    except FileNotFoundError:
        print(f"Error: Excel file not found at '{excel_filepath}'.")
        return []
    except Exception as e:
        print(f"An error occurred while reading the Excel file: {e}")
        return []

# 例:ファイル名を抽出
excel_file = "file_comparison_b_base_merged_optimized.xlsx"
filenames_to_search = extract_filenames_from_excel(excel_file)

if filenames_to_search:
    print(f"Extracted {len(filenames_to_search)} filenames from '{excel_file}':")
    # ファイル名のリストを確認(デバッグ用)
    # for name in filenames_to_search:
    #     print(name)
else:
    print("No filenames extracted or an error occurred.")

このコードでは、pd.read_excel()関数を使ってExcelファイルをDataFrameとして読み込み、指定されたシートと列からファイル名を取得しています。欠損値(NaN)はdropna()で取り除き、結果をリストとして返しています。


Azure AI Searchでのフィルタリング検索プログラム

次に、抽出したファイル名と、filepathおよびpageの条件を使ってAzure AI Searchからドキュメントを検索するプログラムを実装します。提供されたcreate_search_client関数を組み込んで使用します。


import os
from dotenv import load_dotenv
from azure.core.credentials import AzureKeyCredential
from azure.search.documents import SearchClient
from azure.search.documents.models import SearchOptions
import pandas as pd # pandasがインストールされていることを確認

# 環境変数読み込み
load_dotenv()

# 環境変数の取得
# 環境変数名が適切か確認してください。提供された例ではSEARCH_SERVICE_NAME_SRCですが、一般的な命名規則に従っているか、または実際の環境変数名に合わせてください。
SEARCH_SERVICE_NAME = os.getenv("AZURE_SEARCH_SERVICE_NAME") # 実際の環境変数名に合わせて変更
SEARCH_INDEX_NAME = os.getenv("AZURE_SEARCH_INDEX_NAME")   # 実際の環境変数名に合わせて変更
SEARCH_API_KEY = os.getenv("AZURE_SEARCH_API_KEY")         # 実際の環境変数名に合わせて変更

# 環境変数が設定されているか確認
if not all([SEARCH_SERVICE_NAME, SEARCH_INDEX_NAME, SEARCH_API_KEY]):
    print("Error: Azure AI Search environment variables are not set.")
    print("Please set AZURE_SEARCH_SERVICE_NAME, AZURE_SEARCH_INDEX_NAME, and AZURE_SEARCH_API_KEY.")
    exit()

def create_search_client():
    """指定のサービスとインデックスのSearchClientを作成"""
    endpoint = f"https://{SEARCH_SERVICE_NAME}.search.windows.net"
    return SearchClient(
        endpoint=endpoint,
        index_name=SEARCH_INDEX_NAME,
        credential=AzureKeyCredential(SEARCH_API_KEY)
    )

def search_documents_by_filename_filepath_page(search_client: SearchClient, filenames: list):
    """
    指定されたファイル名リスト、filepath、およびpage=1の条件でAzure AI Searchからドキュメントを検索します。

    Args:
        search_client (SearchClient): Azure AI Searchクライアントインスタンス。
        filenames (list): 検索対象のファイル名のリスト。

    Returns:
        list: 検索結果のドキュメントリスト。
    """
    if not filenames:
        print("No filenames provided for search.")
        return []

    # ファイル名のフィルタ条件を構築
    # OData構文では 'eq' (equal) や 'in' 演算子を使用します。
    # ファイル名が多数ある場合、'in' 演算子を使用するのが効率的です。
    # フィルタ文字列の例: filepath eq 'file1.xlsx' or filepath eq 'file2.xlsx' or ...
    # または filepath in ('file1.xlsx', 'file2.xlsx', ...)

    # filepath in (...) 形式のフィルタ文字列を生成
    # filepathフィールドがファイル名と一致すると仮定
    filename_filters = [f"filepath eq '{filename}'" for filename in filenames]
    filename_filter_string = " or ".join(filename_filters)

    # page = 1 のフィルタ条件を追加
    # pageフィールドが数値型または文字列型かによってフィルタ構文が異なります。
    # ここでは文字列型と仮定します。必要に応じて page eq 1 のように変更してください。
    # 文字列型の例: page eq '1'
    # 数値型の例: page eq 1
    page_filter_string = "page eq '1'" # pageフィールドがstring型と仮定

    # 最終的なフィルタ条件を結合
    # filepathとpageの両方の条件を満たすドキュメントを検索
    # (filepath eq 'file1.xlsx' or filepath eq 'file2.xlsx' ...) and page eq '1'
    filter_expression = f"({filename_filter_string}) and {page_filter_string}"

    print(f"Constructed filter expression: {filter_expression}")

    try:
        # '*' は全てのドキュメントに対してフィルタを適用することを意味します。
        # 全文検索は行わず、フィルタリングのみを行います。
        search_results = search_client.search(
            search_text="*", # 全文検索は行わない
            filter=filter_expression,
            select=["original_filename", "filepath", "page", "..."] # 取得したいフィールドを指定
            # 必要に応じて top, skip, order_by などのオプションを追加
        )

        results_list = []
        print("\nSearch Results:")
        for result in search_results:
            results_list.append(result)
            # 検索結果の表示例
            print(f"  Document: {{'filepath': '{result.get('filepath')}', 'page': '{result.get('page')}', ...}}") # 取得したいフィールドに応じて表示を調整

        print(f"\nFound {len(results_list)} documents matching the criteria.")
        return results_list

    except Exception as e:
        print(f"An error occurred during Azure AI Search: {e}")
        return []

# --- メインの処理 ---
if __name__ == "__main__":
    excel_file_path = "file_comparison_b_base_merged_optimized.xlsx" # 実際のファイルパスに修正してください
    sheet_name_to_extract = "不一致データ" # 実際のシート名に修正してください
    column_name_with_filename = "original_filename" # 実際の列名に修正してください

    # Excelファイルからファイル名を抽出
    filenames_for_search = extract_filenames_from_excel(excel_file_path, sheet_name_to_extract, column_name_with_filename)

    if filenames_for_search:
        # Azure AI Searchクライアントを作成
        search_client = create_search_client()

        # 抽出したファイル名リストとフィルタ条件で検索を実行
        search_results = search_documents_by_filename_filepath_page(search_client, filenames_for_search)

        # 必要に応じて検索結果を処理(例: データベースに保存、別のファイルに書き出すなど)
        # print(search_results)
    else:
        print("Could not proceed with search as no filenames were extracted from the Excel file.")

プログラムの詳細解説

上記のプログラムは以下の手順を実行します。

  1. 必要なライブラリをインポートし、.envファイルから環境変数(Azure AI Searchのサービス名、インデックス名、APIキー)を読み込みます。環境変数が設定されていない場合はエラーメッセージを表示して終了します。
  2. create_search_client()関数は、環境変数から取得した情報を使ってAzure AI Searchへの接続クライアント(SearchClient)を作成します。
  3. extract_filenames_from_excel()関数(前のセクションで説明)を呼び出し、指定されたExcelファイルから検索対象のファイル名リストを取得します。
  4. search_documents_by_filename_filepath_page()関数は、以下の処理を実行します。
    • 入力としてSearchClientインスタンスとファイル名リストを受け取ります。
    • ファイル名リストが空の場合は検索を行わず、空のリストを返します。
    • ファイル名リストを使って、OData構文のinまたは複数のeq演算子を用いたfilepathのフィルタ条件文字列を構築します。提供されたファイル名がoriginal_filename列にあることから、検索インデックスのfilepathフィールドに格納されている値がこれらのファイル名と一致すると仮定しています。実際のインデックス定義に合わせてフィールド名を調整してください。
    • page eq '1'という形式で、pageフィールドが文字列「1」と一致するフィルタ条件文字列を作成します。pageフィールドのデータ型が数値型の場合はpage eq 1のように修正が必要です。
    • 構築したfilepathpageのフィルタ条件をandで結合し、最終的なフィルタ式とします。
    • search_client.search()メソッドを呼び出して検索を実行します。
      • search_text="*"とすることで、全文検索は行わずにフィルタリングのみを適用します。
      • filter=filter_expressionで構築したフィルタ条件を指定します。
      • select=["original_filename", "filepath", "page", "..."]で検索結果に含めたいフィールドを指定します。必要に応じて他のフィールドも追加してください。
    • 検索結果をイテレート処理し、各ドキュメントの情報を表示またはリストに格納します。
    • 検索でエラーが発生した場合はエラーメッセージを表示し、空のリストを返します。
  5. メインの処理ブロックでは、Excelファイルのパス、シート名、列名を指定し、関数を呼び出してファイル名を抽出し、検索クライアントを作成して検索を実行します。

検索フィルタリングにおけるFilePathとPageの扱い

Azure AI Searchでは、インデックスのフィールドに対してフィルタリング条件を指定できます。フィルタリングはOData構文を使用して記述します。

  • filepath: このフィールドがドキュメントのファイルパスまたはファイル名を格納していると仮定します。提供されたExcelのoriginal_filenameが、Azure AI Searchインデックスのfilepathフィールドの値と一致する場合、filepath eq 'ファイル名'またはfilepath in ('ファイル名1', 'ファイル名2', ...)のようなフィルタリングが可能です。
  • page: このフィールドがドキュメントのページ番号を格納していると仮定します。ユーザーの要望に合わせて、ページが「1」であるドキュメントに絞り込むためにpage eq '1'(文字列の場合)またはpage eq 1(数値の場合)というフィルタ条件を使用します。

これらの条件を組み合わせることで、特定のファイル名リストに含まれ、かつページ番号が1であるドキュメントを効率的に検索できます。


Azure AI Searchのインデックス構成の確認

このプログラムが正しく機能するためには、Azure AI Searchのインデックスにfilepathpageという名前のフィールドが含まれており、それらがフィルタリング可能(filterable: true)に設定されている必要があります。また、これらのフィールドにExcelファイルから抽出したファイル名とページ番号の情報が正しく取り込まれていることも重要です。

AzureポータルのSearch Explorerを使用すると、インデックスのスキーマや内容を確認できます。これにより、フィールド名やデータ型、そして実際のデータが期待通りにインデックス化されているか検証できます。

Search Explorer Query Tool - Azure AI Search

AzureポータルでのAzure AI Searchサービス概要ページ


検索結果の処理

search_documents_by_filename_filepath_page関数は、検索条件に一致したドキュメントのリストを返します。このリストには、selectオプションで指定したフィールドの値が含まれています。取得した検索結果は、要件に応じて様々な方法で後処理できます。

  • データベースへの保存: 抽出したファイル名と検索で見つかったドキュメントの関連情報をデータベースに記録する。
  • 新しいファイルへの書き出し: 検索結果をCSVやExcelファイルに整形して出力する。
  • 他のシステムとの連携: 検索結果を基に、別のAzureサービス(例: Azure Functions, Logic Apps)をトリガーする。

プログラムのコメントアウトされたセクションで、検索結果を処理する場所を示しています。


考慮事項と最適化

  • ファイル名の量: Excelファイルから抽出されるファイル名の数が非常に多い場合、ODataフィルタ式の長さには上限があります。大量のファイル名でフィルタリングする必要がある場合は、別の検索戦略(例: 別のインデックスを用意してJOIN検索のようなことを行う、または検索クエリ自体を工夫する)を検討する必要があるかもしれません。
  • パフォーマンス: 検索のパフォーマンスは、インデックスのサイズ、レプリカ数、クエリの複雑さ、フィルタリングの効率に依存します。大規模なデータに対して高速な検索が必要な場合は、Azure AI Searchのサービスティアやレプリカ数の調整、インデックスの最適化(例: フィールドの属性設定の見直し)を検討してください。
  • エラーハンドリング: ネットワークエラー、認証エラー、API呼び出しの制限など、様々なエラーが発生する可能性があります。堅牢なアプリケーションを構築するためには、適切なエラーハンドリングを追加することが重要です。
  • 環境変数管理: 環境変数(APIキーなど)は機密情報です。本番環境では、Azure Key Vaultなどの安全な方法で管理することを強く推奨します。

FAQ

Azure AI Searchとは何ですか?

Azure AI Search(旧称 Azure Cognitive Search)は、Microsoft Azureが提供するフルマネージドの検索サービスです。ウェブサイト、アプリケーション、ドキュメントなどのコンテンツに対して、リッチな検索機能(全文検索、フィルタリング、ファセット検索、地理空間検索など)を簡単に実装できます。データのインデックス化、クエリ処理、スケーリングを自動で行います。

ExcelファイルをAzure AI Searchで検索するにはどうすればよいですか?

ExcelファイルなどのドキュメントをAzure AI Searchで検索可能にするには、まずそれらのドキュメントをAzure Blob Storageなどのサポートされているデータソースに配置します。次に、Azure AI Searchでインデクサーを設定します。インデクサーはデータソースからドキュメントを取り込み、内容やメタデータを抽出して検索インデックスに格納するプロセスを自動化します。Excelファイルの内容(テキストデータ)も抽出され、インデックスに含まれます。

filepathとpageでのフィルタリングはどのように行いますか?

Azure AI Searchでは、OData構文を使用してフィルタリングを行います。インデックスにfilepathpageというフィールドがある場合、それぞれがフィルタリング可能に設定されていれば、検索クエリに$filterパラメータを含めることでこれらのフィールドに基づいた絞り込みが可能です。例えば、特定のファイル名とページ番号1でフィルタリングする場合、フィルタ式は filepath eq 'your_filename.xlsx' and page eq '1' (pageが文字列の場合) または filepath eq 'your_filename.xlsx' and page eq 1 (pageが数値の場合)のようになります。複数のファイル名でフィルタリングする場合は、in演算子やor演算子を使用します。

提供されたPythonコードのSearchClientのcredentialは何を意味しますか?

提供されたコードスニペットでは、AzureKeyCredential(SEARCH_API_KEY)が使用されています。これは、Azure AI SearchサービスへのアクセスにAPIキーを使用することを意味します。APIキーは、Azure AI Searchサービスを作成した際に生成される認証キーで、サービスへのリクエストを認証するために使用されます。より安全な方法として、本番環境ではマネージドIDやサービスプリンシパルを用いたAzure Active Directory (Microsoft Entra ID) 認証を使用することも推奨されています。その場合は、AzureKeyCredentialの代わりにDefaultAzureCredentialなどのazure-identityライブラリのCredentialクラスを使用します。

検索結果から特定のフィールドだけを取得するにはどうすればよいですか?

検索結果から特定のフィールドのみを取得するには、SearchClient.search()メソッドのselectオプションを使用します。selectオプションには、取得したいフィールド名のリストを指定します。例えば、ファイルパスとページ番号、そしてドキュメントのタイトルを取得したい場合は、select=["filepath", "page", "title"]のように指定します。これにより、不要なデータの転送量を減らし、検索パフォーマンスを向上させることができます。


推奨される関連クエリ


参照

docs.developers.optimizely.com
About full-text search client

Last updated May 21, 2025
Ask Ithy AI
Download Article
Delete Article