Elasticsearch でのメタデータを活用した検索

BLOG

1. 前書き

前回に引き続き、ホワイトペーパー「Elasticsearchを使った簡易RAGアプリケーションの作成」に
記載した技術的要素を紹介いたします。(*脚注1)1

今回は、メタデータの活用です。

なお、このブログで使用しているサンプルコードは、下記の GitHub リポジトリで公開しています。

blogs/2025-05-search-with-metadata at main · sios-elastic-tech/blogs
A sample code for blogs about elasticsearch. Contribute to sios-elastic-tech/blogs development by creating an account on...

対象者

  • Elastic Cloud のアカウントを持っている人(トライアルライセンスを含む)
  • Elasticsearch の初心者~中級者

できるようになること

  • Elasticsearch でメタデータを活用した検索を行えるようになる。

前提条件

  • Elasticsearch を利用できること (筆者は、Elastic Cloud 8.18.1 Enterprise License で確認)
  • Elasticsearch で日本語の形態素解析の設定を行っていること

https://elastic.sios.jp/blog/creating-an-index-suitable-for-japanese/ で、日本語の形態素解析の設定を行っています。

  • LLM を利用できること (筆者は、Cohere および Ollama で確認)

なお、今回のサンプルでは、説明を簡素にするためにベクトル検索は行いません。キーワード検索のみ行います。

(2025年05月07日時点の情報を元に記載しています。)

2. メタデータ

2.1. メタデータとは?

このブログ内で「メタデータ」と呼んでいるのは、ドキュメントの

  • ファイル名
  • ファイルの種類
  • 作成者
  • 作成日
  • 更新日
  • 文書のタイトル
  • 章のタイトル
  • カテゴリー
  • キーワード
  • タグ
  • 要約
  • 想定されるQ&A

など、ドキュメントに関する情報のことです。

2.2 メタデータを考慮しない検索

有価証券報告書 | IR(投資家情報)‐サイオス株式会社>
サイオス株式会社の有価証券報告書をご覧いただけます。

で公開されているサイオス株式会社の有価証券報告書(PDF)の抜粋を検索する場合を考えます。
(下記に表示している各ブロックが1つのチャンクだとします。)

  • 2018年12月期の有価証券報告書の抜粋

(c) 受注実績
当連結会計年度の受注実績をセグメントごとに示すと、次のとおりであります。

セグメントの名称受注高(千円)前年同期比(%)受注残高(千円)前年同期比(%)
オープンシステム基盤事業7,413,251+7.21,413,726+13.8
アプリケーション事業5,591,926△4.51,324,304+1.4
合計13,005,178+1.82,738,031+7.5
  • 2019年12月期の有価証券報告書の抜粋

(c) 受注実績
当連結会計年度の受注実績をセグメントごとに示すと、次のとおりであります。

セグメントの名称受注高(千円)前年同期比(%)受注残高(千円)前年同期比(%)
オープンシステム基盤事業7,713,257+4.01,431,537+1.3
アプリケーション事業6,175,620+10.41,508,696+13.9
合計13,888,877+6.82,940,234+7.4
  • 2020年12月期の有価証券報告書の抜粋

(c) 受注実績
当連結会計年度の受注実績をセグメントごとに示すと、次のとおりであります。

セグメントの名称受注高(千円)前年同期比(%)受注残高(千円)前年同期比(%)
オープンシステム基盤事業9,073,642+17.61,621,310+13.3
アプリケーション事業6,109,346△1.11,660,413+10.1
合計15,182,988+9.33,281,724+11.6
  • 2021年12月期の有価証券報告書の抜粋

(c) 受注実績
当連結会計年度の受注実績をセグメントごとに示すと、次のとおりであります。

セグメントの名称受注高(千円)前年同期比(%)受注残高(千円)前年同期比(%)
オープンシステム基盤事業9,691,248+6.81,724,230+6.3
アプリケーション事業6,883,678+12.72,407,648+45.0
合計16,574,927+9.24,131,879+25.9
  • 2022年12月期の有価証券報告書の抜粋

(c) 受注実績
当連結会計年度の受注実績をセグメントごとに示すと、次のとおりであります。

セグメントの名称受注高(千円)前年同期比(%)受注残高(千円)前年同期比(%)
オープンシステム基盤事業8,843,132△8.81,850,417+7.3
アプリケーション事業5,772,577△16.12,488,613+3.4
合計14,615,709△11.84,339,030+5.0
  • 2023年12月期の有価証券報告書の抜粋

(c) 受注実績
当連結会計年度の受注実績をセグメントごとに示すと、次のとおりであります。

セグメントの名称受注高(千円)前年同期比(%)受注残高(千円)前年同期比(%)
オープンシステム基盤事業10,503,935+18.82,444,937+32.1
アプリケーション事業5,541,619△4.02,062,760△17.1
合計16,045,555+9.84,507,698+3.9
  • 2024年12月期の有価証券報告書の抜粋

(c) 受注実績
当連結会計年度の受注実績をセグメントごとに示すと、次のとおりであります。

セグメントの名称受注高(千円)前年同期比(%)受注残高(千円)前年同期比(%)
オープンシステム基盤事業14,871,485141.62,742,583112.2
アプリケーション事業6,400,717115.52,477,333120.1
合計21,272,202132.65,219,917115.8

※なお、上記は、pdfplumber を使って PDF から Markdown 形式で抽出したデータの抜粋です。

これらを、1つのインデックスに登録してみます。

インデックスの作成は省略します。
詳細は、下記の github 内のファイルを参照してください。

インデックスを作成した後、ドキュメントを登録していきます。

詳細は、下記の github 内のファイルを参照してください。

POST /sios_securities_report/_doc
{
    "meta.fiscal_year": "2018年12月期",
    "content": """
当連結会計年度の受注実績をセグメントごとに示すと、次のとおりであります。

| セグメントの名称 | 受注高(千円) | 前年同期比(%) | 受注残高(千円) | 前年同期比(%) |
|:--|:--|:--|:--|:--:|
| オープンシステム基盤事業 | 7,413,251 | +7.2 | 1,413,726 | +13.8 |
| アプリケーション事業 | 5,591,926 | △4.5 | 1,324,304 | +1.4 |
| 合計 | 13,005,178 | +1.8 | 2,738,031 | +7.5 |
"""
}

...

POST /sios_securities_report/_refresh

※表の部分は、LLM が回答しやすくなるよう、Markdown 形式で記載します。

※content フィールドには、何年の情報か?が記載されていません。何年の情報か?は、meta.fiscal_year にのみ保持しています。

ドキュメントを登録後に、次の検索クエリーを投げてみます。

GET /sios_securities_report/_search
{
    "query": {
        "match": {
            "content": "2024年12月期 オープンシステム基盤事業 受注高"
        }
    }
}

さて、目的のドキュメント(2024年12月期のオープンシステム基盤事業の受注高を含むドキュメント)が
1位でヒットするでしょうか?

結果は、

...
| オープンシステム基盤事業 | 7,413,251 | ...
...
| オープンシステム基盤事業 | 7,713,257 | ...
...
| オープンシステム基盤事業 | 9,073,642 | ...
...
| オープンシステム基盤事業 | 9,691,248 | ...
...
| オープンシステム基盤事業 | 8,843,132 | ...

となりました。これらは、それぞれ以下のドキュメントとなっています。

  • 2018年12月期の受注高を示すドキュメント
  • 2019年12月期の受注高を示すドキュメント
  • 2020年12月期の受注高を示すドキュメント
  • 2021年12月期の受注高を示すドキュメント
  • 2022年12月期の受注高を示すドキュメント

2024年12月期のドキュメントが1位にならず、しかも、
2024年12月期以外のドキュメントが多数ヒットしています。

このような検索結果になった理由は、検索対象フィールドである “content” の中に “2024年12月期” といった情報が含まれていないためです。
このため、目的のドキュメントを見つけることが困難になっています。

2.3. メタデータを活用した検索

検索時に会計年度(fiscal_year)によるフィルタリングを行うようにしてみます。

GET /sios_securities_report/_search
{
    "query": {
        "bool": {
            "must": {
                "match": {
                    "content": "2024年12月期 オープンシステム基盤事業 受注高"
                }
            },
            "filter": {
                "term": {
                    "meta.fiscal_year": "2024年12月期"
                }
            }
        }
    }
}

結果

...
| オープンシステム基盤事業 | 14,871,485 | ...
...

2024年12月期の受注高を示すドキュメントのみがヒットしました。
(filter で絞り込んでいるので、当然の結果です。)

3. メタデータによるフィルタリングを考慮した検索テンプレート

Python から検索しやすくなるよう、検索テンプレートを登録しておきます。このとき、メタデータによるフィルタリングも行うようにしておきます。

PUT _scripts/search_with_meta_template_202505
{
  "script": {
    "lang": "mustache",
    "source": """{
      "_source": false,
      "fields": [ "meta.fiscal_year", "chunk_no", "content" ],
      "size": "{{size}}{{^size}}10{{/size}}",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "content": "{{query}}"
               }
            }
          ]
          {{#fiscal_year}}
          ,
          "filter": [
            {
              "term": {
                "meta.fiscal_year": "{{fiscal_year}}"
              }
            }
          ]
          {{/fiscal_year}}
        }
      }
    }
    """
  }
}

4. サンプルソース

下記に、メタデータによるフィルタリングを考慮した RAG のサンプルソースを公開しています。

blogs/2025-05-search-with-metadata at main · sios-elastic-tech/blogs
A sample code for blogs about elasticsearch. Contribute to sios-elastic-tech/blogs development by creating an account on...

Elasticsearch + Streamlit + LLM による RAG です。(RAGを使わずに検索だけ行うことも可能です。)

LLM には、Cohere または Ollama を利用できるようにしています。

Cohere を利用する場合は、Cohere の API Key が必要です。

Ollama を利用する場合は、別途、Ollama および利用するモデルのインストールが必要です。

参考にしてみてください。

5. 実行例

サンプルアプリの実行方法については、下記のリンクを参照してください。

blogs/2025-05-search-with-metadata/README.md at main · sios-elastic-tech/blogs
A sample code for blogs about elasticsearch. Contribute to sios-elastic-tech/blogs development by creating an account on...

下記に実行例を表示します。

5.1. メタデータを使わずに検索した場合

「2024年のオープンシステム基盤事業の受注高はいくら?」という検索を行ったにもかかわらず、2024年のドキュメントが上位にヒットしていません。他の年のドキュメントが上位にヒットしてしまっています。これは、検索対象の content フィールドに「年」の情報を保持していないためです。

5.2. メタデータを活用して検索した場合

左側のラジオボタンで、あらかじめ《2024年12月期》を選択してから「2024年のオープンシステム基盤事業の受注高はいくら?」という検索を行った結果です。

事前に会計年度によるフィルタリングを行っているので、2024年12月期のドキュメントのみがヒットしています。

5.3. メタデータを使わずにRAGを行った場合

※これは、Ollama で、hf.co/mmnga/ELYZA-Shortcut-1.0-Qwen-7B-gguf:Q4_K_M を使って回答させた例です。

検索結果には、2024年以外のドキュメントも含まれており、かつ、返却されたデータには「2024年」というキーワードが含まれていません。そのため、LLM からの回答が「わかりません。」となっています。

5.4. メタデータを活用してRAGを行った場合

※これは、Ollama で、hf.co/mmnga/ELYZA-Shortcut-1.0-Qwen-7B-gguf:Q4_K_M を使って回答させた例です。

左側のラジオボタンで、あらかじめ《2024年12月期》を選択してから「オープンシステム基盤事業の受注高はいくら?」という問い合わせを行った結果です。(クエリーから「2024年の」という文字列を除去していますが、これは、「2024年」という条件をメタデータによるフィルタリングで実施しており、LLMに渡すと単なるノイズになってしまうためです。)

事前に会計年度によるフィルタリングを行っているので、2024年12月期のドキュメントのみが検索結果として返却され、それにもとづいて正しい回答が返却されています。

6. 参考情報

メタデータを使った検索に関する、Elasticsearch 社のブログ(英語)

Advanced RAG techniques: Data processing & ingestion - Elasticsearch Labs
This blog explores and implements advanced RAG techniques which may increase performance, focusing on data processing & ...
Advanced RAG techniques: Querying & testing a RAG pipeline - Elasticsearch Labs
This blog discusses and implements RAG techniques which may increase performance, focusing on querying and testing an ad...

上記の Elastic Search Labs のブログでは、

  • キーフレーズ
  • 潜在的な質問
  • エンティティ

を GPT-4o などを使って生成しています。
生成した情報をメタ情報としてドキュメントに付与し、検索時に利用するサンプルが紹介されています。

7. まとめ

このようにメタデータを活用すると目的のドキュメントを見つけやすくなります

検索の手助けになるようなメタデータは、ドキュメントの内容や検索要件によるので
一概にコレとは言えませんが、おおよそ下記のようなものがメタデータとなると思われます。

  • ファイル名
  • ファイルの種類
  • 作成者
  • 作成日
  • 更新日
  • 文書のタイトル
  • 章のタイトル
  • カテゴリー
  • キーワード
  • タグ
  • 要約
  • 想定されるQ&A

このようなメタデータのうち自分たちの検索に有用と思われるものを保持し、検索時に利用することで目的のドキュメントを見つけやすくなります。

さらに、今回のサンプルアプリのように、検索結果が正確になることで RAG の回答精度が上昇する場合もあります。

要件に合わせて、メタデータを考慮した検索を検討してみてください。


  1. ホワイトペーパー「Elasticsearchを使った簡易RAGアプリケーションの作成」は、下記からダウンロードできます。
    (E-mailアドレスなどの入力が必要です。)
    https://elastic.sios.jp/whitepaper/
    ↩︎