<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[基本 - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[基本 - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/jp/search-labs/blog/category/basics</link>
    </image>
    <link>https://www.elastic.co/jp/search-labs/blog/category/basics</link>
    <atom:link href="https://www.elastic.co/jp/search-labs/rss/category/basics.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[jp]]></language>
    <lastBuildDate>Mon, 28 Sep 2026 12:33:01 GMT</lastBuildDate>
  <item>
    <title><![CDATA[Azure AKS Automatic に Elasticsearch をデプロイする方法]]></title>
    <description><![CDATA[部分的に管理された Elasticsearch セットアップ構成のために、AKS Automatic と ECK を使用して Azure に Kibana とともに Elasticsearch をデプロイする方法を学習します。]]></description>
    <content:encoded><![CDATA[<p>この記事は、さまざまなインフラストラクチャを使用して Elasticsearch をインストールする方法を説明するシリーズの一部です。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt45071aec499098c0/6a17fe770b0beda3d1dd37f4/0a65ca8b62fd8a42d7751b8f4bf057e33d877304-940x458.png" alt="Elasticsearchの導入の取り組み" /><p>ECK はマーケットプレイスベースの Elastic Cloud ソリューションよりも大幅に多くの労力を必要としますが、Kubernetes オペレーターがシステム オーケストレーションとノードのスケーリングを処理するため、VM を自分でデプロイするよりも自動化されています。</p><p>今回は、Automatic を使用して Azure Kubernetes Service (AKS) を操作します。他の記事では、 <a href="https://www.elastic.co/search-labs/blog/azure-elasticsearch-vm-deployment">Azure VM</a>と<a href="https://www.elastic.co/search-labs/blog/deploy-elasticsearch-azure-marketplace">Azure Marketplace の</a>使用方法について学習します。</p><h2>AKS Automatic とは何ですか?</h2><p><a href="https://learn.microsoft.com/en-us/azure/aks/intro-aks-automatic">Azure Kubernetes Service (AKS) は、クラスターのセットアップを自動的に</a>管理し、リソースを動的に割り当て、Kubernetes の柔軟性を維持しながらセキュリティのベスト プラクティスを統合するため、開発者はコンテナー イメージからデプロイされたアプリケーションまでを数分以内に実行できます。</p><p>AKS Automatic は、クラスター管理のオーバーヘッドの大部分を排除し、シンプルさと柔軟性のバランスを適切にとります。適切な選択はユースケースによって異なりますが、次のことを計画すると決定が容易になります。</p><ul><li><p><strong>テスト環境をデプロイする:</strong>デプロイは高速かつ簡単なので、簡単な実験や短期間のクラスターに最適です。</p></li><li><p><strong>厳密な VM、ストレージ、またはネットワーク要件なしで作業:</strong> AKS Automatic では定義済みのデフォルトが提供されるため、それがニーズに合えば、追加の構成を行う必要がなくなります。</p></li><li><p><strong>Kubernetes を初めて使用する場合:</strong> AKS Automatic はクラスターのセットアップの大部分を処理するため、学習曲線が短縮され、チームはアプリケーションに集中できるようになります。</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9e74556cda9b56bd/6a17fe791d1b830cdc93e681/2e4c09b8c5e0ce5e8ea9c369626a373b7030a5ba-854x489.png" alt=" Azure Kubernetes Service (AKS) 自動クラスターを作成する方法" /><p>Elasticsearch では、Elastic Stack の Kubernetes デプロイメント オーケストレーションを簡素化する公式 Elastic Kubernetes オペレーターである<a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud on Kubernetes</a> (ECK) を使用します。</p><h2>AKS Automaticの設定方法</h2><p>1. <a href="https://azure.microsoft.com/">Microsoft Azure ポータル</a>にログインします。</p><p>2.<strong>右上の</strong><strong>Cloud Shell</strong>ボタンをクリックし、コンソールにアクセスしてそこから AKS クラスターをデプロイします。あるいは、 <a href="https://learn.microsoft.com/en-us/azure/cloud-shell/overview">Azure Cloud Shell を</a>使用することもできます。</p><p><em><strong>チュートリアル中にプロジェクト ID を自分のものに更新することを忘れないでください。</strong></em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt06acd165140f9ab5/6a17fe7ae9ea876604a9c849/0aa60605777c0a6e3aef8faa4e54388c2cb582c8-624x495.png" alt="" /><p><em>AKS を開くと、上のスクリーンショットのようになります。</em></p><p>3. aks-preview Azure CLI 拡張機能をインストールします。このプレビュー バージョンでは、クラスターの作成時に<code>--sku automatic</code>を選択できるようになり、AKS Automatic 機能が有効になります。</p>az extension add --name aks-preview<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt703add301bb94b89/6a17fe7c57726213da1bce20/2e05ab67fc554c5fb5208683c179fdeaeadd95db-624x56.png" alt="" /><p><em>このメッセージが表示された場合、AKS 拡張機能が正しくインストールされたことを意味します。</em></p><p>4. <code>az feature register</code>コマンドを使用して<a href="https://learn.microsoft.com/en-us/azure/azure-app-configuration/concept-feature-management">機能フラグ</a>を登録する</p>az feature register --namespace Microsoft.ContainerService --name AutomaticSKUPreview<p><em>作成した機能サブスクリプションの詳細が表示されます。</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt024ca2930c3a02e3/6a17fe7ee9ea87e003a9c84d/3aca710c1f312ba91de461638e518386919ec722-801x138.png" alt="" /><p>登録ステータスが「<em><strong>登録中</strong></em>」から「<em><strong>登録済み</strong></em>」に変わるまで確認します。登録が完了するまでに数分かかる場合があります。</p>az feature show --namespace Microsoft.ContainerService --name AutomaticSKUPreview<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0b8d717b484bd461/6a17fe7f445de951aa4d0382/186486b08ab8e1c372efaff50f10cbddeaf4e0cd-844x177.png" alt="" /><p>変更を伝播するには<code>az provider register</code>を実行します。</p>az provider register --namespace Microsoft.ContainerService<p>5. リソースグループを作成する</p><p>リソース グループは、管理およびデプロイされる Azure リソースの論理グループです。</p>az group create --name elastic-resource --location eastus<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbbf4b6e75c2dd560/6a17fe8163baff6114741e72/d1952269e97d94f914020754bd02702f9eafd037-770x212.png" alt="" /><p>6. Autopilot クラスターを作成します。これを<em><strong>myAKSAutomaticCluster に</strong></em>名前を付け、先ほど作成したリソース グループを使用します。AKS がリソースを割り当てるには、<a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dpsv5-series"> Standard_D4pds_v5</a> 、<a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dldsv5-series"> Standard_D4lds_v5</a> 、<a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dadsv5-series"> Standard_D4ads_v5</a> 、<a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/ddsv5-series"> Standard_D4ds_v5</a> 、 <a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/ddv5-series">Standard_D4d_v5</a><a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/ddv4-series"> 、 Standard_D4d_v4</a> 、<a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/general-purpose/dsv3-series"> Standard_DS3_v2</a> 、<a href="https://learn.microsoft.com/en-us/azure/virtual-machines/sizes/memory-optimized/dv2-dsv2-series-memory"> Standard_DS12_v2</a> のいずれかの VM サイズで<em><strong> 16 個の vCPU が使用可能であることを確認してください。</strong></em></p>az aks create \
    --resource-group elastic-resource \
    --name myAKSAutomaticCluster \
    --sku automatic \
    --generate-ssh-keys<p><em>*</em> <em><code>MissingSubscriptionRegistration</code></em><em>エラーが発生した場合は、不足しているサブスクリプションを使用して手順4に戻ってください。たとえば、</em> <em><code>The subscription is not registered to use namespace '</code></em> <em><strong><code>microsoft.insights</code></strong></em> <em><code>'</code></em><em>実行中のサブスクリプションが必要です。</em><em><code>az provider register --namespace Microsoft.Insights.</code></em></p><p>対話型ログインに従ってください:</p><p><em>「az login」の実行を求めるメッセージが表示されます。そのコマンドを実行してから待つ必要があります。</em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc711a241388cf786/6a17fe83dbb4fff454fb5929/14c0238f755fe6347519e69d3cb28c0fa52ec044-775x203.png" alt="" /><p>7. 準備ができるまで待ちます。作成には約10分かかります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc389eecd12e3b2c8/6a17fe8425daab0b2408a442/eb00c3ad18f884f47db6645b196808ebec07c1fc-797x177.png" alt="" /><p>8. kubectl コマンドライン アクセスを構成します。</p>az aks get-credentials --resource-group elastic-resource --name myAKSAutomaticCluster<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfdb13d3950950b06/6a17fe85b1e11319e179f4bd/5136d72a5d455345b0b6205bb232c4bdf7762998-793x52.png" alt="" /><p><em>インストールした拡張機能によって AKS Automatic が有効になっていることに注意してください。</em></p><p>9. ノードがデプロイされたことを確認します。</p>kubectl get nodes<p>禁止エラー メッセージが表示されます。エラーからユーザー ID をコピーします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4b2bb8558e1a39f4/6a17fe87a292991ce3d02ea8/d6c021fa54f4db00d2d795f5ba9b5a93376d03cd-818x47.png" alt="" /><p>10. ユーザーを AKS アクセス制御に追加します。</p><p>AKS ID を取得します。コマンドからの出力をコピーします。</p>az aks show --resource-group elastic-resource  --name myAKSAutomaticCluster --query id --output tsv<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0ebc4fa29348d561/6a17fe896df7317a3b0a1166/22a1cdc538bd379812a752c6a368a0651000abb8-810x36.png" alt="" /><p>AKS ID とユーザーのプリンシパル ID を使用してロールの割り当てを作成します。</p>az role assignment create --role "Azure Kubernetes Service RBAC Cluster Admin" --assignee &lt;PRINCIPAL_ID&gt; --scope &lt;AKS_ID&gt;<p>11. ノードが再度デプロイされたことを確認します。</p>kubectl get nodes<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltda416366f0e53d49/6a17fe8ab1e113f87c79f4c1/c9b3a5c1cc540ef732c3e7f60b0a973bdbd0b6fd-617x99.png" alt="" /><p>12. Kubernetes (ECK) オペレーターに Elastic Cloud をインストールします。</p># Install ECK Custom Resource Definitions
kubectl create -f https://download.elastic.co/downloads/eck/2.16.1/crds.yaml

# Install the ECK operator
kubectl apply -f https://download.elastic.co/downloads/eck/2.16.1/operator.yaml<p>13. デフォルト値を使用して、単一ノードの Elasticsearch インスタンスを作成しましょう。</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 9.0.0
  nodeSets:
  - name: default
    count: 1
    config:
      node.store.allow_mmap: false
EOF<p>デフォルトの AKS マシンの<code>vm.max_map_count</code>値が低すぎるため、 <code>nmap</code>を無効にしました。本番環境では無効にすることは推奨されませんが、 <code>vm.max_map_count</code>の値を増やすことは推奨されます。これを行う方法の詳細については、<a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/virtual-memory">ここを</a>参照してください。</p><p>14. Kibana シングルノード クラスターもデプロイしましょう。Kibana の場合は、ロード バランサーを追加します。これにより、デバイスから Kibana にアクセスするために使用できる外部 IP が提供されます。</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: quickstart
spec:
  version: 9.0.0
  http:
    service:
      spec:
        type: LoadBalancer
  count: 1
  elasticsearchRef:
    name: quickstart
EOF<p>デフォルトでは、AKS Automatic はロード バランサーをパブリックとして構成します。メタデータ アノテーションを設定することで動作を変更できます。</p><p><code>service.beta.kubernetes.io/azure-load-balancer-internal: "true"</code></p><p>15. ポッドが実行中であることを確認します。</p>kubectl get pods<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltea98380109a7a0b1/6a17fe8c4b055dda6c43241e/213a897176c0af6cea19c7c777cfaf8734e3ee6e-616x84.png" alt="" /><p>16.Elasticsearch のバージョン、ノード、健全性などのより具体的な統計情報を取得するには、 <code>kubectl get elasticsearch</code>と<code>kubectl get kibana</code>を実行することもできます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt89119d59582673d9/6a17fe8d4b055d4257432422/c84988e725ef892eddd8fb7e5a03d58c35a8f9d6-470x62.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte714550df3504cd4/6a17fe8f7b54f982a28b3b19/452dd03d314cd00c8a3c19e19862b968592a0435-415x62.png" alt="" /><p>17. サービスにアクセスします。</p>kubectl get svc<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc9c24dc9b78a354/6a17fe900b0beda9f8dd37f8/b2d3e8f368be22b89aa2ed4d4d514f97dd6cbabd-624x115.png" alt="" /><p>これにより、EXTERNAL-IP の下に Kibana の<a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/accessing-services">外部 URL</a>が表示されます。ロードバランサーのプロビジョニングには数分かかる場合があります。<em><strong>EXTERNAL-IP の値をコピーします。</strong></em></p><p>18. 'elastic' ユーザーの Elasticsearch パスワードを取得します。</p>kubectl get secret quickstart-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltec8ef3a4df60e7a8/6a17fe9263baff3381741e76/bd74537f8c35c4e027c518913fdb0a0524621d56-624x31.png" alt="" /><p>19. ブラウザから<strong>Kibana にアクセスします</strong>。</p><p>a. URL: https://&lt;EXTERNAL_IP&gt;:5601</p><p>b. ユーザー名:elastic</p><p>c. パスワード:c44A295CaEt44D6xIzN6Zs5m (前の手順から)</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7e8fbd1593bae329/6a17fe937b54f91d7c8b3b1d/a601112527d80721b292328ed8da58386d2837eb-463x503.png" alt="" /><p>20.ブラウザから Elastic Cloud にアクセスすると、ようこそ画面が表示されます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9ad7cd3196eb7dbe/6a17fe95b1e11336a579f4c5/f91e71fa961d215a8d886601d1a9fc5c452ce329-1999x1256.png" alt="" /><p>ノードの変更やサイズ変更など、Elasticsearch クラスターの仕様を変更する場合は、新しい設定で YML マニフェストを再度適用できます。</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 9.0.0
  nodeSets:
    - name: default
      count: 2
      config:
        node.store.allow_mmap: false
      podTemplate:
        spec:
          containers:
            - name: elasticsearch
              resources:
                requests:
                  memory: 1.5Gi
                  cpu: 2
                limits:
                  memory: 1.5Gi
                  cpu: 2
EOF<p>この例では、さらに 1 つのノードを追加し、RAM と CPU を変更します。ご覧のとおり、 <code>kubectl get elasticsearch</code>には 2 つのノードが表示されています。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdfe6ff383e03814e/6a17fe974b055dd514432426/4b139a476b50933d45d99e09479112817964f76a-624x60.png" alt="" /><p>Kibana にも同じことが当てはまります。</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: quickstart
spec:
  version: 9.0.0
  http:
    service:
      spec:
        type: LoadBalancer
  count: 1
  elasticsearchRef:
    name: quickstart
  podTemplate:
    spec:
      containers:
        - name: kibana
          env:
            - name: NODE_OPTIONS
              value: "--max-old-space-size=1024"
          resources:
            requests:
              memory: 0.5Gi
              cpu: 0.5
            limits:
              memory: 1Gi
              cpu: 1
EOF<p>コンテナのCPU/RAMと<a href="https://nodejs.org/">Node.jsの</a>メモリ使用量（ <a href="https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib">max-old-space-size</a> ）を調整できます。</p><p><a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/volume-claim-templates">既存のボリュームクレームを縮小することはできない</a>ことに留意してください。アップデートを適用した後、オペレーターは最小限の中断時間で変更を加えます。</p><p>不要なコストを避けるために、テストが完了したらクラスターを忘れずに削除してください。</p>az aks delete --name myAKSAutomaticCluster --resource-group elastic-resource<h2>まとめ</h2><p>Azure AKS Automatic を ECK と併用すると、Elasticsearch と Kibana をデプロイするためのバランスの取れたソリューションが提供されます。これにより、運用の複雑さが軽減され、スケーリングと更新が自動化され、Kubernetes の柔軟性が活用されます。このアプローチは、インフラストラクチャの詳細をすべて手動で管理することなく、信頼性が高く、繰り返し可能で、保守可能なデプロイメント プロセスを求めるチームに最適であり、テスト環境と本番環境の両方にとって実用的な選択肢となります。</p><h2>今後の見通し</h2><p>Kubernetes について詳しく知りたい場合は、次の公式ドキュメントをご覧ください。</p><ul><li><p><a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Kubernetes 上の Elastic Cloud | Elastic ドキュメント</a></p></li><li><p><a href="https://learn.microsoft.com/en-us/azure/aks/intro-aks-automatic">Azure Kubernetes Service (AKS) Automatic (プレビュー) の概要</a></p></li><li><p><a href="https://azure.github.io/AKS/2024/05/22/aks-automatic">AKS Automatic - AKSエンジニアリングブログ</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-azure-aks-automatic-deployment</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-azure-aks-automatic-deployment</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Eduard Martin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt58d08dac9d3586db/6a17fe983e9e45002eba16e7/4d821659a606e04390b09215e9a0d32eb01f0d1b-854x489.png" length="0" type="image/png"/>
    <pubDate>Fri, 14 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch で構造化ドキュメントの再帰チャンクを構成する]]></title>
    <description><![CDATA[チャンク サイズ、セパレーター グループ、カスタム セパレーター リストを使用して Elasticsearch で再帰チャンクを設定し、構造化ドキュメントのインデックスを最適に作成する方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>8.16 以降、ユーザーは長いドキュメントをセマンティック テキスト フィールドに取り込むときに使用するチャンキング戦略を構成できるようになりました。9.1 / 8.19 では、正規表現のリストを使用してドキュメントをチャンク化する、新しい構成可能な再帰チャンク化戦略を導入しました。チャンク化の目的は、長いドキュメントを関連するコンテンツをカプセル化するセクションに分割することです。既存の戦略では、テキストを単語/文の粒度で分割しますが、構造化された形式 (例:Markdown では、区切り文字列で定義されたセクション内に関連コンテンツが含まれることがよくあります (例:ヘッダー)。このような種類のドキュメントでは、構造化ドキュメントの形式を活用してより適切なチャンクを作成するための再帰チャンキング戦略を導入しています。</p><h2>再帰チャンキングとは何ですか?</h2><p>再帰チャンク化では、指定されたセクション分離パターンのリストを反復処理して、必要な最大チャンク サイズを満たすまで、ドキュメントを段階的に小さなセグメントに分割します。</p><h3>再帰チャンクを構成するにはどうすればよいですか?</h3><p>以下は、再帰チャンク化に対してユーザーが指定できる構成可能な値です。</p><ul><li><p>(必須) <code>max_chunk_size</code> : チャンク内の最大単語数。</p></li><li><p>次のいずれか:</p><ul><li><p><code>separators</code>: ドキュメントをチャンクに分割するために使用される正規表現文字列パターンのリスト。</p></li><li><p><code>separator_group</code>: 特定の種類のドキュメントに使用するために Elastic によって定義された区切り文字のデフォルト リストにマップされる文字列。現在、 <code>markdown</code>と<code>plaintext</code>が利用可能です。</p></li></ul></li></ul><h3>再帰チャンキングはどのように機能しますか?</h3><p>入力ドキュメント、 <code>max_chunk_size</code> (単語単位で測定)、および区切り文字列のリストが与えられた場合の再帰チャンク化のプロセスは次のとおりです。</p><ol><li><p>入力ドキュメントがすでに最大チャンク サイズ内である場合は、入力全体にわたる単一のチャンクを返します。</p></li><li><p>区切り文字の出現に基づいてテキストを潜在的なチャンクに分割します。潜在的なチャンクごとに:</p><ol><li><p>潜在的なチャンクが最大チャンク サイズ内である場合は、ユーザーに返すチャンクのリストに追加します。</p></li><li><p>それ以外の場合は、潜在的なチャンクのテキストのみを使用して、リスト内の次のセパレーターを使用して分割し、手順 2 から繰り返します。試す区切り文字がもう残っていない場合は、文ベースのチャンクに戻ります。</p></li></ol></li></ol><h2>再帰チャンクの設定例</h2><p>チャンク サイズとは別に、再帰チャンク化の主な構成は、ドキュメントを分割するために使用するセパレーターを選択することです。どこから始めればよいかわからない場合は、Elasticsearch では一般的なユースケースに使用できるデフォルトのセパレーター グループがいくつか用意されています。</p><h3>セパレーターグループの活用</h3><p>セパレーター グループを利用するには、チャンク設定を構成するときに使用するグループの名前を指定するだけです。例えば：</p>"chunking_settings": {
    "strategy": "recursive",
    "max_chunk_size": 25,
    "separator_group": "plaintext"
}<p>これにより、区切りリスト<code>["(?&lt;!\\n)\\n\\n(?!\\n)", "(?&lt;!\\n)\\n(?!\\n)")]</code>を利用する再帰的なチャンク化戦略が提供されます。これは、2 つの改行文字とそれに続く 1 つの改行文字で分割する、一般的なプレーン テキスト アプリケーションに適しています。</p><p>セパレーターリストを利用するセパレーターグループ<code>markdown</code>も提供しています。</p>[
"\n# ",
       "\n## ",
       "\n### ",
       "\n#### ",
       "\n##### ",
       "\n###### ",
       "\n^(?!\\s*$).*\\n-{1,}\\n",
       "\n^(?!\\s*$).*\\n={1,}\\n"
]<p>この区切りリストは、6 つの見出しレベルとセクション区切り文字のそれぞれに分割する一般的なマークダウンの使用例に適しています。</p><p>リソース (推論エンドポイント/セマンティック テキスト フィールド) を作成すると、その時点のセパレーター グループに対応するセパレーターのリストが構成に保存されます。セパレーター グループが後日更新されても、既に作成されたリソースの動作は変更されません。</p><h3>カスタム区切りリストの利用</h3><p>定義済みの区切り文字グループのいずれかが使用ケースに適していない場合は、ニーズに合った区切り文字のカスタム リストを定義できます。区切りリスト内に正規表現を指定できることに注意してください。以下は、カスタムセパレーターを使用して構成されたチャンク設定の例です。</p>"chunking_settings": {
    "strategy": "recursive",
    "max_chunk_size": 25,
    "separators": ["\n\n", "\n", "&lt;my-custom-separator&gt;"]
}<p>上記のチャンク化戦略では、 2 つの改行文字、続いて 1 つの改行文字、最後に文字列<code>“&lt;my-custom-separator&gt;”</code>で分割されます。</p><h2>再帰チャンキングの実際の例</h2><p>再帰チャンキングの実際の例を見てみましょう。この例では、上位 2 つのヘッダー レベルを使用してマークダウン ドキュメントを分割するセパレーターのカスタム リストとともに、次のチャンク設定を使用します。</p>"chunking_settings": {
    "strategy": "recursive",
    "max_chunk_size": 25,
    "separators": ["\n# ", "\n## "]
}<p>単純なチャンクなしの Markdown ドキュメントを見てみましょう。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltdb5f41d1bd43ba50/6a17e831e9ea87c1d8a9c5f3/3a5507f4a1288065097231548e5b18e240508785-1302x1446.png" alt="チャンクなしのMarkdown文書" /><p>ここで、上で定義したチャンク設定を使用してドキュメントをチャンク化してみましょう。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfffda162c7b9c87a/6a17e83296142aefa8eb1b0b/a3313c4c40ff39b8dbcdd7c4878c723f088e6c1a-1600x1187.png" alt="Elasticsearchでドキュメントをチャンク化する" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt96f65346a8e09e3a/6a17e834445de9157b4d015e/79a2921943191ea631df94c9d465818ec8d3e738-1600x1206.png" alt="2番目のセパレーターで分割 - Elasticsearchでドキュメントをチャンク化する" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt28381c8f85aedf07/6a17e836ec0f89801e5a6640/459e695cce7540267422396b9a62ff4ad35f61db-1600x1260.png" alt="Elasticsearch で文ベースのチャンクを分割した後のドキュメントの最終チャンク" /><p>注: 各チャンク (チャンク 3 を除く) の末尾の改行は強調表示されませんが、実際のチャンク境界内に含まれます。</p><h3>今すぐ再帰チャンキングを始めましょう!</h3><p>この機能の利用方法の詳細については、チャンク設定の構成に関するドキュメントを参照してください。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/recursive-chunking-structured-documents-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/recursive-chunking-structured-documents-elasticsearch</guid>
    <category><![CDATA[基本]]></category>
    <category><![CDATA[Elastic内部の実情]]></category>
    <category><![CDATA[AI]]></category>
    <dc:creator><![CDATA[Daniel Rubinstein]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf442dc4941f37be7/6a17e838505ac3eaf8ad8b3d/591872e31880768ca927507654a621addc0d124d-1600x960.png" length="0" type="image/png"/>
    <pubDate>Tue, 11 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Kibana に Elasticsearch クエリルール UI を導入]]></title>
    <description><![CDATA[Elasticsearch クエリ ルール UI を使用して、オーガニック ランキングに影響を与えずに Kibana のカスタマイズ可能なルールセットを使用して検索クエリにドキュメントを追加または除外する方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>検索エンジンの役割は、関連性のある結果を返すことです。ただし、セールの強調、季節商品の優先、スポンサー商品の展示など、それ以上のビジネスニーズがあり、開発者は検索クエリでこれを常に実行できるとは限りません。</p><p>さらに、これらのユースケースは通常、時間に敏感であり、一般的な開発段階 (コード ブランチを作成してから新しいリリースを待つ) を実行するのは時間のかかるプロセスです。</p><p>では、このプロセス全体を API 呼び出しだけで、あるいは Kibana で数回クリックするだけで実行できたらどうなるでしょうか?</p><h2>クエリルールUI</h2><p>Elasticsearch 8.10 では、<a href="https://www.elastic.co/blog/introducing-query-rules-elasticsearch-8-10"><strong>クエリ ルール</strong></a>と<a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/retrievers/rule-retriever"><strong>ルール リトリーバー</strong></a>が導入されました。これらは、ルールに基づいてオーガニック検索結果のランキングに影響を与えずに、<a href="https://www.elastic.co/docs/reference/query-languages/query-dsl/query-dsl-pinned-query"><em>ピン留めされた結果を</em></a>クエリに挿入するように設計されたツールです。宣言的かつシンプルな方法で、結果の上にビジネス ロジックを追加するだけです。</p><p>クエリ ルールの一般的な使用例は次のとおりです。</p><ul><li><p><strong>プロモーション対象商品やセール品の強調表示</strong>: セール中の商品やスポンサー商品を上部に表示します。</p></li><li><p><strong>コンテキストまたは地理位置情報による除外</strong>: 地域の規制により表示が許可されていない場合は、特定のアイテムを非表示にします。</p></li><li><p><strong>主要な結果を優先する</strong>: オーガニックランキングに関係なく、人気のある検索や固定検索が常に上位に表示されるようにします。</p></li></ul><p>インターフェースにアクセスしてこれらのツールを操作するには、Kibana サイドメニューをクリックし、関連性の下にある<strong>クエリルール</strong>に移動する必要があります<strong>。</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltac12541cddd58e36/6a170853a29299941cd00fc2/242e33e89d1a07ffa0e76009c46b3a9236722741-458x1010.png" alt="Elasticsearchの関連性に基づくクエリルールへのアクセス" /><p>クエリ ルール メニューが表示されたら、<strong>最初のルール セットの作成をクリックします。</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcc28329c0f3c3aa9/6a17085547d49c67e22d893b/30b3a91bbbf243d314cf38298e01ca5cff784430-1600x945.png" alt="Elasticsearchで最初のクエリルールルールセットを作成する" /><p>次に、ルールセットに名前を付ける必要があります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb37d271297a4f148/6a170856a29299782cd00fc6/26c5462f88678867776f933b5655ca0df0d72a16-708x446.png" alt="Elasticsearch でのクエリルールのルールセットの命名" /><p>各ルールを定義するフォームには、次の 3 つの主要コンポーネントがあります。</p><ul><li><p><strong>基準</strong>: ルールを適用するために満たす必要がある条件。たとえば、「query_string フィールドに値<em>Christmas</em>が含まれている場合」や「country フィールドに<em>CO の場合」などです。</em></p></li><li><p><strong>アクション</strong>: これは、条件が満たされたときに発生する動作です。ピン留め（ドキュメントを上位の結果に固定する）したり、除外（ドキュメントを非表示にする）したりできます。</p></li><li><p><strong>メタデータ</strong>: これらはクエリの実行時にクエリに付随するフィールドです。これらには、ユーザーの情報 (場所や言語など) や検索データ (query_string) を含めることができます。これらは、ルールを適用するかどうかを決定するための基準で使用される値です。</p></li></ul><h2>例: 人気商品</h2><p>さまざまな商品を扱う電子商取引サイトがあると想像してみましょう。指標をチェックすると、コンソール カテゴリで最も売れているアイテムの 1 つが「DualShock 4 ワイヤレス コントローラー」であることがわかります。特に、ユーザーが「PS4」または「PlayStation 4」というキーワードを検索した場合に多く見られます。そこで、ユーザーがこれらのキーワードを検索するたびに、この製品を結果の最上位に表示することにしました。</p><p>まず、Bulk API リクエストを使用して各アイテムのドキュメントをインデックス化します。</p>POST _bulk
{ "index": { "_index": "products", "_id": "1" } }
{ "id": "1", "name": "PlayStation 4 Slim 1TB", "category": "console", "brand": "Sony", "price": 1200 }
{ "index": { "_index": "products", "_id": "2" } }
{ "id": "2", "name": "DualShock 4 Wireless Controller", "category": "accessory", "brand": "Sony", "price": 250 }
{ "index": { "_index": "products", "_id": "3" } }
{ "id": "3", "name": "PlayStation 4 Camera", "category": "accessory", "brand": "Sony", "price": 200 }
{ "index": { "_index": "products", "_id": "4" } }
{ "id": "4", "name": "PlayStation 4 VR Headset", "category": "accessory", "brand": "Sony", "price": 900 }
{ "index": { "_index": "products", "_id": "5" } }
{ "id": "5", "name": "Charging Station for DualShock 4", "category": "accessory", "brand": "Sony", "price": 80 }<p>クエリに介入しない場合、アイテムは通常 4 番目の場所に表示されます。クエリは次のとおりです。</p>GET products/_search
{
 "query": {
   "match": {
     "name": "PlayStation 4"
   }
 }
}<p>そして結果はこちらです</p>{
 "took": 1,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 5,
     "relation": "eq"
   },
   "max_score": 0.6973252,
   "hits": [
     {
       "_index": "products",
       "_id": "3",
       "_score": 0.6973252,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 0.6260078,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 0.6260078,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "2",
       "_score": 0.08701137,
       "_source": {
         "id": "2",
         "name": "DualShock 4 Wireless Controller",
         "category": "accessory",
         "brand": "Sony",
         "price": 250
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.07893815,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}<p>これを変更するためのクエリ ルールを作成しましょう。まず、次のようにルールセットに追加しましょう。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1576d4f4a2e60548/6a170858cdacbfccb07d298d/fdc42646fb3e76a09bca7d19047a76efe343f7a2-1600x650.png" alt="Elasticsearchでクエリルールのルールセットを編集する方法" /><p>または同等の<a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-query-rules-put-ruleset">API リクエスト</a>:</p>PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "rule-1232",
      "type": "pinned",
      "criteria": [
        {
          "type": "exact",
          "metadata": "query_string",
          "values": [
            "PS4",
            "PlayStation 4"
          ]
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "2"
          }
        ]
      }
    }
  ]
}<p>クエリで<strong>ルールセット</strong>を使用するには、クエリ ルール タイプを使用する必要があります。この種のクエリは、主に次の 2 つの部分で構成されます。</p>GET /products/_search
{
 "retriever": {
   "rule": {
     "retriever": {
       "standard": {
         "query": {
           "match": { "name": "PlayStation 4" }
         }
       }
     },
     "match_criteria": {
       "query_string": "PlayStation 4"
     },
     "ruleset_ids": ["my-rules"]
   }
 }
}<ul><li><p><strong>match_criteria</strong> : ユーザーのクエリと比較するために使用されるメタデータです。この例では、query_string フィールドの値が「PlayStation 4」の場合にルールセットがアクティブになります。</p></li><li><p><strong>query</strong> : 検索してオーガニック検索結果を取得するために使用される実際のクエリ。</p></li></ul><p>この方法では、最初にオーガニッククエリを実行し、次に Elasticsearch がルールセットのルールを適用します。</p>{
 "took": 17,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 5,
     "relation": "eq"
   },
   "max_score": 1.7014122e+38,
   "hits": [
     {
       "_index": "products",
       "_id": "2",
       "_score": 1.7014122e+38,
       "_source": {
         "id": "2",
         "name": "DualShock 4 Wireless Controller",
         "category": "accessory",
         "brand": "Sony",
         "price": 250
       }
     },
     {
       "_index": "products",
       "_id": "3",
       "_score": 0.6973252,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 0.6260078,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 0.6260078,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.07893815,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}<h2>例: ユーザーベースのメタデータ</h2><p>クエリ ルールのもう 1 つの興味深い応用は、メタデータを使用して、ユーザーまたは Web ページからのコンテキスト情報に基づいて特定のドキュメントを表示することです。</p><p>たとえば、数値として表されるユーザーのロイヤルティ レベルに基づいて、アイテムやカスタマイズされたセールを強調表示したいとします。</p><p>これを実現するには、このメタデータをクエリに直接取り込んで、その値が特定の基準を満たしたときにルールがアクティブになるようにします。</p><p>まず、ロイヤルティ レベルの高いユーザーだけが閲覧できるドキュメントをインデックスします。</p>POST _bulk
{ "index": { "_index": "products", "_id": "6" } }
{ "id": "6", "name": "PlayStation Plus Deluxe Card - 12 months", "category": "membership", "brand": "Sony", "price": 300 }<p>ここで、同じルールセット内に新しいルールを作成し、loyalty_level が 80 以上の場合にアイテムが結果の上部に表示されるようにします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt158578005df8c76d/6a17085aab7f086dc0db9de3/58de12dff93305440608f51465462fcc68653a08-1421x496.png" alt="Elasticsearchでクエリルールのルールセットを編集する方法" /><p>ルールとルールセットを保存します。</p><p>同等の REST リクエストは次のとおりです。</p>PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "pin-premiun-user",
      "type": "pinned",
      "criteria": [
        {
          "type": "gte",
          "metadata": "loyalty_level",
          "values": [
            80
          ]
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "6"
          }
        ]
      }
    }
  ]
}<p>ここで、クエリを実行するときに、メタデータに新しいパラメータ<strong>royality_level</strong>を含める必要があります。ルールの条件が満たされると、新しいドキュメントが結果の上部に表示されます。</p><p>たとえば、loyalty_level が 80 のクエリを送信する場合:</p>POST /products/_search
{
  "retriever": {
    "rule": {
      "retriever": {
        "standard": {
          "query": {
            "match": {
              "name": "PlayStation"
            }
          }
        }
      },
      "match_criteria": {
        "query_string": "PlayStation",
        "loyalty_level": 80
      },
      "ruleset_ids": ["my-rules"]
    }
  }
}<p>結果の上部にロイヤルティ ドキュメントが表示されます。</p>{
  "took": 31,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 1.7014122e+38,
    "hits": [
      {
        "_index": "products",
        "_id": "6",
        "_score": 1.7014122e+38,
        "_source": {
          "id": "6",
          "name": "PlayStation Plus Deluxe Card - 12 months",
          "category": "membership",
          "brand": "Sony",
          "price": 300
        }
      },
      {
        "_index": "products",
        "_id": "3",
        "_score": 0.5054567,
        "_source": {
          "id": "3",
          "name": "PlayStation 4 Camera",
          "category": "accessory",
          "brand": "Sony",
          "price": 200
        }
      },
      {
        "_index": "products",
        "_id": "1",
        "_score": 0.45618832,
        "_source": {
          "id": "1",
          "name": "PlayStation 4 Slim 1TB",
          "category": "console",
          "brand": "Sony",
          "price": 1200
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 0.45618832,
        "_source": {
          "id": "4",
          "name": "PlayStation 4 VR Headset",
          "category": "accessory",
          "brand": "Sony",
          "price": 900
        }
      }
    ]
  }
}<p>以下の場合、ロイヤルティ レベルが 70 であるため、ルールは満たされず、アイテムは上部に表示されません。</p>POST /products/_search
{
  "retriever": {
    "rule": {
      "retriever": {
        "standard": {
          "query": {
            "match": {
              "name": "PlayStation"
            }
          }
        }
      },
      "match_criteria": {
        "query_string": "PlayStation",
        "loyalty_level": 70
      },
      "ruleset_ids": ["my-rules"]
    }
  }
}<p>結果は次のとおりです。</p>{
  "took": 7,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 4,
      "relation": "eq"
    },
    "max_score": 0.5054567,
    "hits": [
      {
        "_index": "products",
        "_id": "3",
        "_score": 0.5054567,
        "_source": {
          "id": "3",
          "name": "PlayStation 4 Camera",
          "category": "accessory",
          "brand": "Sony",
          "price": 200
        }
      },
      {
        "_index": "products",
        "_id": "1",
        "_score": 0.45618832,
        "_source": {
          "id": "1",
          "name": "PlayStation 4 Slim 1TB",
          "category": "console",
          "brand": "Sony",
          "price": 1200
        }
      },
      {
        "_index": "products",
        "_id": "4",
        "_score": 0.45618832,
        "_source": {
          "id": "4",
          "name": "PlayStation 4 VR Headset",
          "category": "accessory",
          "brand": "Sony",
          "price": 900
        }
      },
      {
        "_index": "products",
        "_id": "6",
        "_score": 0.3817649,
        "_source": {
          "id": "6",
          "name": "PlayStation Plus Deluxe Card - 12 months",
          "category": "membership",
          "brand": "Sony",
          "price": 300
        }
      }
    ]
  }
}<h2>例: 即時除外</h2><p><strong>DualShock 4 ワイヤレス コントローラー (ID 2)</strong>が一時的に入手できず、販売できないとします。そのため、ビジネス チームは、ドキュメントを手動で削除したり、何らかのデータ処理が開始されるのを待ったりする代わりに、当面は検索結果からドキュメントを削除することにしました。</p><p>先ほど人気アイテムに適用したのと同様のプロセスを使用しますが、今回は<em>[Pinned]</em>ではなく<em>[Exclude]</em>を選択します。このルールは一種のブラックリストとして機能します。クエリが実行されるたびに除外が機能するように、条件を<strong>「常時」</strong>に変更します。</p><p>ルールは次のようになります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt38564c0b7f4a6ee2/6a17085c1949f78692e7a989/f10971e4f1bc9520105111adfa3a476581a27130-1600x623.png" alt="Elasticsearch の即時除外ルールセットの例" /><p>変更を適用するには、ルールとルールセットを保存します。同等の REST リクエストは次のとおりです。</p>PUT _query_rules/my-rules
{
  "rules": [
    {
      "rule_id": "rule-6358",
      "type": "pinned",
      "criteria": [
        {
          "type": "always"
        }
      ],
      "actions": {
        "docs": [
          {
            "_index": "products",
            "_id": "2"
          }
        ]
      }
    }
  ]
}<p>ここで、クエリを再度実行すると、以前のルールではアイテムをピン留めするはずだったにもかかわらず、アイテムが結果に表示されなくなっていることがわかります。これは、<strong>除外がピン留め結果よりも優先される</strong>ためです。</p>{
 "took": 6,
 "timed_out": false,
 "_shards": {
   "total": 1,
   "successful": 1,
   "skipped": 0,
   "failed": 0
 },
 "hits": {
   "total": {
     "value": 4,
     "relation": "eq"
   },
   "max_score": 2.205655,
   "hits": [
     {
       "_index": "products",
       "_id": "3",
       "_score": 2.205655,
       "_source": {
         "id": "3",
         "name": "PlayStation 4 Camera",
         "category": "accessory",
         "brand": "Sony",
         "price": 200
       }
     },
     {
       "_index": "products",
       "_id": "1",
       "_score": 1.9738505,
       "_source": {
         "id": "1",
         "name": "PlayStation 4 Slim 1TB",
         "category": "console",
         "brand": "Sony",
         "price": 1200
       }
     },
     {
       "_index": "products",
       "_id": "4",
       "_score": 1.9738505,
       "_source": {
         "id": "4",
         "name": "PlayStation 4 VR Headset",
         "category": "accessory",
         "brand": "Sony",
         "price": 900
       }
     },
     {
       "_index": "products",
       "_id": "5",
       "_score": 0.69247496,
       "_source": {
         "id": "5",
         "name": "Charging Station for DualShock 4",
         "category": "accessory",
         "brand": "Sony",
         "price": 80
       }
     }
   ]
 }
}<h2>まとめ</h2><p><strong>クエリ ルールを</strong>使用すると、コードを変更することなく関連性を簡単に調整できます。新しい<strong>Kibana</strong> <strong>UI</strong>では、これらの変更を数秒で行うことができるため、お客様とビジネス チームは検索結果をより細かく制御できるようになります。</p><p>クエリ ルールは、電子商取引以外にも、サポート ポータルでトラブルシューティング ガイドを強調表示したり、ナレッジ ベースで重要な社内ドキュメントを表示したり、ニュース サイトで最新ニュースを宣伝したり、期限切れの求人やコンテンツの一覧を除外したりするなど、さまざまなシナリオで活用できます。ユーザーの役割や地域によって制限されたコンテンツを非表示にするなど、コンプライアンス ルールを適用することもできます。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-query-rules-ui-introduction</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-query-rules-ui-introduction</guid>
    <category><![CDATA[基本]]></category>
    <category><![CDATA[開発者エクスペリエンス]]></category>
    <dc:creator><![CDATA[Jhon Guzmán]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt565ed0eb407e098d/6a17085d8b73cb363d189fb1/1fb10bd31c509cc9b9bb4f71f49970f140e6c36f-1600x945.png" length="0" type="image/png"/>
    <pubDate>Fri, 07 Nov 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[AWS MarketplaceでElasticsearchをデプロイする方法]]></title>
    <description><![CDATA[このステップバイステップガイドでは、AWSマーケットプレイスでElastic Cloudサービスを使用してElasticsearchをセットアップし、実行する方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>この記事では、Marketplaceの提供を利用してAWS上でElasticsearchをデプロイする方法を学びます。</p><p>Elastic Cloud Service on AWSを使用します。これは、AWSのネイティブインフラストラクチャーを介してすべてのElastic Stackコンポーネントの導入とオーケストレーションを簡素化するオフィシャルのマネージドElasticsearch Serviceです。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6c1107b202d48147/6a16f67d92262a04071cc077/f15814051b53b50bec38f9a9f515a1e6dc08a56c-884x440.png" alt="" /><p>AWS EC2でのElasticsearchのインストールと設定方法を学びたい方は、<a href="https://www.elastic.co/search-labs/blog/elasticsearch-on-aws-ec2-deployment-guide">このブログ</a>をご覧ください。
</p><h2>AWS Marketplaceとは？</h2><p><a href="https://aws.amazon.com/marketplace"><strong>Elastic on AWS Marketplace</strong></a>は、完全マネージド型の検索・分析エクスペリエンスを提供します。インフラの提供、security、スケーリングは AWS が処理し、開発者は検索アプリケーションの構築に集中できます。これにより、チームは搭載のAWS統合を使用して、エンタープライズグレードのElasticsearchクラスターを数分でデプロイできるようになります。</p><h2>Elastic on AWS Marketplaceを使用するのはどのような場合ですか？</h2><p>Elastic on AWS Marketplaceは、既存のAWSインフラストラクチャを持ち、運用オーバーヘッドなしでマネージドサービス、組み込みセキュリティ、シームレスなAWS統合を備えたElasticsearchを導入したいと考えている組織に最適です。</p><h2>AWSマーケットプレイスでElastic Cloudをセットアップする方法</h2><h3>ステップ1 : AWS Marketplaceにアクセスする</h3><p>1。<a href="https://console.aws.com/">AWS</a>にログインしてください。</p><ul><li><p>検索バーでAWS Marketplaceを検索します。</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7b4a64a97929ca0/6a16f67e60084b1ee43c4333/fc9928f79482c2c01e33978c88d390a2bfa2a3bf-1600x340.png" alt="" /><p>2. 左側のナビゲーションパネルで<strong>Discover products</strong>をクリックし、「Elasticsearch」を検索します。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta3efc233beb103ab/6a16f680b0367d681572babd/ca4232271cb13ebfe33de406ecaec085033ec8a0-1454x760.png" alt="" /><p>3. <strong>Elastic Cloud (Elasticsearch Service)</strong>をクリックします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd7fe524f5d0cc84e/6a16f682cdacbfabdf7d27c4/e59aa276e55532f2ac3461d0ca983af4d41ad7a6-1600x611.png" alt="" /><h3>ステップ 2: サービスに登録する</h3><p>1. <strong>購入オプション</strong>を選択するか、<strong>無料で試す</strong>をクリックします。</p><p>2.<strong>価格の詳細</strong>、<strong>利用規約</strong>、<strong>購入の詳細</strong>を確認します。</p><p>3. <strong>登録</strong>ボタンをクリックします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt027c8adb6bfa2b73/6a16f683a292995855d00de4/1c30d12b6b1061e76771d518011e522285f939f1-1600x290.png" alt="" /><p>4. 次に、Elasticアカウントをセットアップする必要があります。AWSの手順に従います。</p><p>a. 「統合を有効にする」ボタンをクリックします</p><p>b.「サインインまたはベンダーアカウントを作成」ボタンをクリックします。</p><p>c. 「テンプレートを起動」ボタンをクリックします。</p><p>d. 「ソフトウェアを起動」ボタンをクリックします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d290ceb4c00c3ca/6a16f685839dfa35f6dcfc9b/879d9f0f01406e1955e1b38a2f6f2192ef040344-852x722.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt20832a47a3a5ce7b/6a16f68767045b0c8b45bf92/fc59be78cf776aa12867f40810598419576cbd39-1600x1143.png" alt="" /><h3>ステップ3. Elasticで新しいアカウントを設定する</h3><p>1. Elasticアカウントを作成してください。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2a47e1e23a0be123/6a16f68875879e400ffe15c0/5efeaf0737062a55470b17b67651f220e12183f2-986x905.png" alt="" /><p>2. メールアドレスを確認する</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltaad961a0644018b5/6a16f68a0811ae0734e9feb6/e0cfaac278614e317ce278935040bfa5a58edd13-853x894.png" alt="" /><p>3.お名前と会社情報をインプットしてください。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt52f4a502993fa5d4/6a16f68b2b835fb4b9f4afc4/d5658fe66c3b1bcced73e822eae006846f0ddd9e-997x903.png" alt="" /><p>4. Elasticの簡単なアンケートに回答する</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt375dca1904b2f0c1/6a16f68dcdacbf4f8d7d27c8/a3f53c00dadfd22f7d739a920c87d5f387182833-892x805.png" alt="" /><p>5. Elastic Cloudをマネージド環境でホストする地域を選択する（デフォルトで実際のAWSリージョンが選択されます）</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0c23f8b8b63af517/6a16f68fb0367d6a6072bac1/c1dcdf3bf91c305821daaa25a60aa03be6454c1c-1207x1032.png" alt="" /><p>6. Elasticがデプロイされるのを待つ</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd88a26701fb26db5/6a16f69075879ef0d8fe15cc/50903e57ebea7cc47bdfabf4750b4ba2a7a91148-1370x1266.png" alt="" /><p>7. 導入がAWS Marketplaceサブスクリプションに接続される</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt822e8acb553ffac4/6a16f69275879ed57ffe15d0/3bb731e2d5de5053ccecb77e45dbdbcdaf294dba-1600x1288.png" alt="" /><h2>サブスクリプションをキャンセルする</h2><p>サブスクリプションをキャンセルするには以下の手順に従います。</p><p>1. <a href="https://console.aws.com/">AWSコンソール</a>に移動します。</p><p>検索バーで「AWS Marketplace」と検索してください。<strong>AWS Marketplace</strong>をクリックします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7a19e162d4cb818a/6a16f694839dfa21a6dcfc9f/aeed3d1e67b4cef91934de257a6fd6daa9737a12-1600x554.png" alt="" /><p>2．<strong>Elastic Cloudサブスクリプション</strong>をクリックします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta189d9ff9b518243/6a16f695a292991b60d00de8/04e6cc41850226df223dbe2d1b0e4b45265f6c39-1600x564.png" alt="" /><p>3. <strong>アクション</strong>ボタンをクリックし、次に<strong>サブスクリプションをキャンセル</strong>をクリックします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt40fc41f3911b8b66/6a16f6971949f70896e7a7a9/e33d334ea6541c637a223de3ebd6209def75a6d3-1600x1039.png" alt="" /><p>4．キャンセルを確認し、<strong>はい</strong>をクリックして、<strong>サブスクリプションをキャンセル</strong>ボタンをクリックします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3eb1839197854313/6a16f699ab7f08469fdb9c31/b73b3187168adc7aefdd46f95be33c1bce3da1e4-1103x698.png" alt="" /><p>5. 確認メッセージがページ上部に表示されます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt513bdb916a3bff8e/6a16f69a1949f74c5de7a7ad/c5ba66a23d535e866a8b458e5aca82c5f0b93037-1600x639.png" alt="" /><h2>次のステップ</h2><p>単一の導入と3つのプロジェクトが含まれ 7日間の<a href="https://aws.amazon.com/marketplace/pp/prodview-voru33wi6xs7k">Elastic Cloud (Elasticsearch Service)</a> 無料トライアルでElastic Cloudの旅を始めましょう。AWSアカウントにサインインし、「購入オプションを表示」をクリックして、Elastic<a href="https://aws.amazon.com/marketplace/pp/prodview-voru33wi6xs7k"> Cloud (Elasticsearch Service)</a>でElasticのSearch AI Platformをすぐに使い始められます。このトライアルでは、インフラストラクチャ管理のオーバーヘッドなしで、検索、セキュリティ、および監視ソリューションに完全にアクセスできます。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/aws-elasticsearch-service-set-up</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/aws-elasticsearch-service-set-up</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Eduard Martin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltcbf8a044704b64d5/6a16f69ccf4f25d524b2cf3f/a80776d2ef85db26f850d932339fac2d26b90278-1086x620.png" length="0" type="image/png"/>
    <pubDate>Fri, 03 Oct 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch のシャードとレプリカ: 実践ガイド]]></title>
    <description><![CDATA[Elasticsearch のシャードとレプリカの概念を習得し、それらを最適化する方法を学習します。]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch は、スケーラビリティとフォールト トレランスの問題に対処する分散システムを Lucene 上に構築することで、Lucene のパワーを強化します。また、JSON ベースの REST API も公開されているため、他のシステムとの相互運用性が非常に簡単になります。</p><p>Elasticsearch のような分散システムは非常に複雑になる可能性があり、パフォーマンスと安定性に影響を与える要因が多数あります。<strong>シャードは</strong>Elasticsearch の最も基本的な概念の 1 つであり、その仕組みを理解することで Elasticsearch クラスターを効果的に管理できるようになります。</p><p>この記事では、プライマリ シャードとレプリカ シャードとは何か、それらが Elasticsearch クラスターに与える影響、さまざまな需要に合わせてそれらを調整するためのツールについて説明します。</p><h2>破片を理解する</h2><p>Elasticsearch インデックス内のデータは膨大な量にまで増大する可能性があります。管理しやすいように、すべてのデータはインデックスに保存され、インデックスはいくつかの<strong>シャード</strong>に分割されます。各 Elasticsearch シャードは Apache Lucene インデックスであり、個々の Lucene インデックスには Elasticsearch インデックス内のドキュメントのサブセットが含まれています。このようにインデックスを分割すると、リソースの使用量を制御できます。Apache Lucene インデックスには、2,147,483,519 (2³¹ - 129) ドキュメントの制限があります。</p><p>場合によっては、再バランス調整のためにインデックスをノード間で移動する必要があります。このプロセスは時間とリソースの両方を大量に消費する可能性があるため、インデックスが大きくなりすぎないようにする必要があります。これにより、回復時間を管理しやすい状態に保つことができます。さらに、インデックスは常に結合する必要がある Lucene セグメントで構成されているため、セグメントが大きくなりすぎないことが重要です。これらの理由から、Elasticsearch はインデックス データを<strong>プライマリ シャード</strong>と呼ばれるより小さく管理しやすいチャンクに分割し、複数のマシン間でより簡単に分散できるようにします。<strong>レプリカ</strong>シャードは、対応するプライマリ シャードの正確なコピーであり、その機能についてはこの記事の後半で説明します。</p><p>適切な数のシャードを持つことはパフォーマンスにとって重要です。したがって、事前に計画を立てるのが賢明です。クエリが異なるシャード間で並列に実行されると、各シャードが異なるノードに配置され、クラスター内に十分なノードがある場合に限り、単一のシャードで構成されたインデックスよりも高速に実行されます。ただし同時に、シャードはインデックス化されたデータとクラスター メタデータの両方に関して、メモリとディスク領域を消費します。シャードが多すぎると（オーバーシャーディングとも呼ばれます）、クエリ、インデックス要求、および管理操作が遅くなる可能性があるため、適切なバランスを維持することが重要です。</p><p>プライマリ シャードの数は、<strong>特定のインデックス インスタンスの</strong>インデックス作成時に定義されます。後でプライマリ シャードの数を変更する必要がある場合は、<strong>サイズ変更 API を</strong>使用できます (<a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-split">分割</a>(プライマリ シャードを増やす)、<a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-shrink">縮小</a>(プライマリ シャードを減らす)、または<a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-indices-clone">複製</a>(レプリカの新しい設定でプライマリ シャードの数は同じ))。これらの操作は、Lucene セグメントをコピーし、<strong>すべてのドキュメントの完全な再インデックスを回避します</strong>。インデックスを作成するときに、インデックスの設定としてプライマリ シャードとレプリカ シャードの数を設定できます。</p>PUT /sensor
{
   "settings" : {
       "index" : {
           "number_of_shards" : 6,
           "number_of_replicas" : 2
       }
   }
}<p>(シャードまたはレプリカの数を指定しない場合、Elasticsearch 7.0 以降、両方のデフォルト値は 1 になります)。理想的なシャードの数は、インデックス内のデータ量に基づいて決定する必要があります。一般的に、<a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards">最適なシャードは 10 ～ 50 GB のデータを保持し、シャードあたりのドキュメント数は 2 億未満である必要があります</a>。たとえば、1 日に約 300 GB のアプリケーション ログが蓄積されると予想される場合、それらをホストするのに十分な数のノードがあれば、そのインデックスに約 10 個のシャードを持つことが妥当です。</p><p>シャードは、その存続期間中に、次のようなさまざまな状態を経る可能性があります。</p><ul><li><p><strong>初期化中:</strong>シャードが使用される前の初期状態。</p></li><li><p><strong>開始済み:</strong>シャードがアクティブでリクエストを受信できる状態。</p></li><li><p><strong>再配置中:</strong>シャードが別のノードに移動されている途中に発生する状態。これは、たとえば、ノードのディスク容量が不足している場合など、特定の状況下では必要になることがあります。</p></li><li><p><strong>未割り当て:</strong>割り当てに失敗したシャードの状態。これが発生すると理由が提供されます。たとえば、シャードをホストしているノードがクラスター内になくなった場合<em>(NODE_LEFT)</em> 、または閉じたインデックスに復元された場合<em>(EXISTING_INDEX_RESTORED) などです。</em></p></li></ul><p>すべてのシャード、その状態、およびその他のメタデータを表示するには、次のリクエストを使用できます。</p>GET _cat/shards<p>特定のインデックスのシャードを表示するには、URL にインデックスの名前を追加します (例: sensor)。</p>GET _cat/shards/sensor<p>このコマンドは、次の例のような出力を生成します。デフォルトでは、表示される列にはインデックスの名前、名前（つまりシャードの数、プライマリ シャードかレプリカか、シャードの状態、ドキュメント数、ディスク上のサイズ、シャードが配置されているノードの IP アドレスとノード ID が表示されます。</p>sensor 5 p STARTED    0  283b 127.0.0.1 ziap
sensor 5 r UNASSIGNED                  
sensor 2 p STARTED    1 3.7kb 127.0.0.1 ziap
sensor 2 r UNASSIGNED                  
sensor 3 p STARTED    3 7.2kb 127.0.0.1 ziap
sensor 3 r UNASSIGNED                  
sensor 1 p STARTED    1 3.7kb 127.0.0.1 ziap
sensor 1 r UNASSIGNED                  
sensor 4 p STARTED    2 3.8kb 127.0.0.1 ziap
sensor 4 r UNASSIGNED                  
sensor 0 p STARTED    0  283b 127.0.0.1 ziap
sensor 0 r UNASSIGNED<h2>レプリカを理解する</h2><p>各シャードにはデータのコピーが 1 つ含まれますが、インデックスにはシャードの複数のコピーが含まれる場合があります。したがって、シャードには、<strong>プライマリ シャード</strong>とコピー、または<strong>レプリカ</strong>の 2 種類があります。プライマリ シャードの各レプリカは常に異なるノードに配置されるため、ノード障害が発生した場合でもデータの高可用性が確保されます。冗長性とデータ損失やダウンタイムの防止の役割に加えて、レプリカはクエリをプライマリ シャードと並行して処理できるため、検索パフォーマンスが向上し、処理速度が向上します。</p><p>プライマリ シャードとレプリカ シャードの動作にはいくつかの重要な違いがあります。どちらもクエリを処理できますが、インデックスリクエスト（つまりインデックスにデータを追加するなどの処理は、レプリカ シャードに複製される前に、まずプライマリ シャードを通過する必要があります。前述のように、プライマリ シャードが使用できなくなった場合 (たとえば、ノードの切断やハードウェア障害などにより)、レプリカが昇格してその役割を引き継ぎます。</p><p>レプリカはノード障害の際に役立ちますが、インデックス作成時にメモリ、ディスク容量、計算能力を消費するため、レプリカを多くしすぎないことが重要です。プライマリ シャードとレプリカのもう 1 つの違いは、インデックスの作成後はプライマリ シャードの数を変更できないのに対し、レプリカの数はインデックス設定を更新することでいつでも動的に変更できることです。</p><p>レプリカに関して考慮すべきもう 1 つの要素は、利用可能なノードの数です。同じノードに同じデータのコピーが 2 つあると、ノードに障害が発生した場合に保護が提供されないため、レプリカは常にプライマリ シャードとは異なるノードに配置されます。その結果、システムが<em>n 個の</em>レプリカをサポートするには、クラスター内に少なくとも<em>n + 1 個の</em>ノードが必要になります。たとえば、クラスター内に 2 つのノードがあり、インデックスが 6 つのレプリカで構成されている場合、割り当てられるレプリカは 1 つだけです。一方、7 つのノードを持つシステムは、1 つのプライマリ シャードと 6 つのレプリカを完全に処理できます。</p><h2>シャードとレプリカの最適化</h2><p>プライマリ シャードとレプリカ シャードの適切なバランスを持つインデックスが作成された後でも、インデックスの周囲のダイナミクスは時間の経過とともに変化するため、これらを監視する必要があります。たとえば、時系列データを扱う場合、最近のデータを持つインデックスは、一般的に古いデータを持つインデックスよりもアクティブになります。これらのインデックスを調整しないと、要件が大きく異なるにもかかわらず、すべて同じ量のリソースを消費することになります。</p><p>ロールオーバー インデックス API を使用すると、新しいインデックスと古いインデックスを分離できます。特定のしきい値（ディスク上のインデックスのサイズ、ドキュメントの数、または年齢）に達すると、新しいインデックスを自動的に作成するように設定できます。この API は、シャードのサイズを制御するのにも役立ちます。インデックス作成後はシャードの数を簡単に変更できないため、ロールオーバー条件が満たされない限り、シャードにはデータが蓄積され続けます。アクセス頻度が低い古いインデックスの場合、インデックスの縮小と強制マージは、メモリとディスクのフットプリントを削減する 2 つの異なる方法です。前者はインデックス内のシャードの数を減らし、後者は Lucene セグメントの数を減らし、削除されたドキュメントによって使用されていたスペースを解放します。</p><h2>Elasticsearchの基盤となるプライマリシャードとレプリカシャード</h2><p>Elasticsearch は、膨大な量のデータのための分散ストレージ、検索、分析プラットフォームとして高い評価を得ています。しかし、このような規模で事業を展開する場合、必然的に課題が生じます。そのため、プライマリ シャードとレプリカ シャードの仕組みを理解することは、Elasticsearch にとって非常に重要かつ基本的なことであり、プラットフォームの信頼性とパフォーマンスを最適化するのに役立ちます。</p><p>これらがどのように機能し、どのように最適化するかを知ることは、より堅牢でパフォーマンスの高い Elasticsearch クラスターを実現するために重要です。クエリ応答が遅くなったり、頻繁に停止したりする場合は、この知識がこれらの障害を克服する鍵となる可能性があります。</p><p><a href="https://www.elastic.co/docs/deploy-manage/distributed-architecture/clusters-nodes-shards">クラスター、ノード、シャード、シャードの</a><a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards">サイズ設定方法</a>、<a href="https://www.elastic.co/docs/deploy-manage/distributed-architecture/shard-allocation-relocation-recovery">シャードの割り当てと回復の</a>詳細については、Elasticsearch の公式ドキュメントを参照してください。</p><p>このトピックは、 <a href="https://youtu.be/sAySPSyL2qE">Elastic コミュニティ YouTube チャンネルの入門コースとしてもご利用いただけます。</a></p><p>最後に、ノード、シャード、レプリカについて心配したくない場合は、 <a href="https://www.elastic.co/docs/deploy-manage/deploy/elastic-cloud/serverless">Elastic Cloud Serverless を</a>試してみてください。この Elastic Cloud オファリングは Elastic によって完全に管理され、ワークロードに合わせて自動的に拡張されます。無料トライアルを利用すると、サーバーレス アプローチのその他の利点を理解するのに役立ちます。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-shards-and-replicas-guide</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-shards-and-replicas-guide</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Piotr Przybyl]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt71dd92d939d383a2/6a17e9d53e03d769c44f2cc7/7775c44f01f2516c4ff4cce6d6bbe9e7b2c38908-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Thu, 14 Aug 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[ユニークなパターンを明らかにする: Elasticsearch における重要な用語の集約ガイド]]></title>
    <description><![CDATA[重要な用語の集計を使用してデータから洞察を得る方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch では、<a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significantterms-aggregation">重要な用語の集約</a>により<a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-terms-aggregation">、最も一般的な用語</a>を超えて、データセット内の統計的に異常な値を見つけます。これにより、貴重な洞察や明らかでないパターンを発見することができます。重要な用語の集約により、次の 2 つの便利なパラメータを含む応答が提供されます。</p><ul><li><p><strong>bg_count (背景カウント):</strong>親データセットで見つかったドキュメントの数</p></li><li><p><strong>doc_count:</strong>結果データセットで見つかったドキュメントの数</p></li></ul><p>たとえば、携帯電話の販売データセットでは、次のようにして iPhone 16 の販売に関する重要な用語を探すことができます。</p>GET phone_sales_analysis/_search
{
 "size": 0,
 "query": {
   "term": {
     "phone_model": {
       "value": "iPhone 16"
     }
   }
 },
 "aggs": {
   "significant_cities": {
     "significant_terms": {
       "field": "city_region",
       "size": 1
     }
   }
 }
}<p>すると、応答は次のようになります。</p>{
 "aggregations": {
   "significant_cities": {
     "doc_count": 122,
     "bg_count": 424,
     "buckets": [
       {
         "key": "Houston",
         "doc_count": 12,
         "score": 0.1946481360617346,
         "bg_count": 14
       }

     ]
   }
 }
}<p>ヒューストンは、データセット全体の都市のトップ 10 にも、iPhone 16 のトップ都市にも入っていません。しかし、重要な用語の集約により<em><strong>、この都市では他のデータと比較して iPhone 16 が不均衡に多く購入されている</strong></em>ことが示されました。数字を詳しく見てみましょう:</p><ul><li><p><strong>最上位レベル:</strong></p><ul><li><p><strong>doc_count: 122 —</strong>クエリは合計122の文書と一致しました</p></li><li><p><strong>bg_count: 424 —</strong>背景セット（すべての販売文書）には424の文書が含まれています</p></li></ul></li><li><p><strong>ヒューストンのバケット:</strong></p><ul><li><p><strong>doc_count: 12 —</strong>ヒューストンは122件の検索結果のうち12件に出現します</p></li><li><p><strong>bg_count: 14 —</strong>ヒューストンは、背景データセット内の合計424の文書のうち14に登場します。</p></li></ul></li></ul><p>これは、合計 424 件の購入のうち、ヒューストンで発生したのは 14 件のみであり、これは全購入の 3.3% であることを示しています。しかし、iPhone 16の販売だけに注目すると、122件中12件がヒューストンで発生しており、これは9.8%で、データセット全体の3倍にあたります。これは大きな数字です。</p><p>これを視覚的に表すと次のようになります: city_region ごとの総売上高。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blted1af6606708267e/6a17f5d614800960e1b488d5/f31335b0b7793650025f941820f238dd35bfb09f-1486x1066.png" alt="" /><p>ヒューストンには 14 件の売上があり、データセット内で売上高が 14 番目に多い都市であることがわかります。</p><p>ここで、フィルターを適用して iPhone 16 の販売のみを調べると、ヒューストンでの販売数が 12 件となり、この特定のモデルの販売数が最も多い都市として 2 番目に多い都市になります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd2882d5e87d02406/6a17f5d71d1b83851e93e5b2/6516040db77e6c62af5541a74c723b18008ad3c6-1472x1038.png" alt="" /><h2>重要な用語の理解</h2><p>Elasticのドキュメントによると、<a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significantterms-aggregation">重要な用語の集約は次のとおり</a>です。</p><p><em>「前景セットと背景セット間で測定された人気度に大きな変化があった用語を検索します。」</em></p><p>つまり、統計メトリックを使用して、データのサブセット (フォアグラウンド セット) 内の用語の頻度を、データの親セット (バックグラウンド セット) 内の同じ用語の頻度と比較します。この方法では、スコアリングはデータ内での用語の出現頻度ではなく、統計的有意性を反映します。</p><p>重要な用語の集約と通常の用語の集約の主な違いは次のとおりです。</p><ul><li><p>重要な用語はデータのサブセットを比較しますが、用語の集約はクエリの結果のデータセットに対してのみ機能します。</p></li><li><p>用語の集約から得られる結果はデータセット内で最も一般的な用語ですが、重要な用語から得られる結果はデータセットを一意にする要素を見つけるために一般的な用語を無視します。</p></li><li><p>用語の集約と同様に、メモリではなくディスクからデータを取得する必要があるため、重要な用語はパフォーマンスに大きな影響を与える可能性があります。</p></li></ul><h2>実践応用（消費者行動分析）</h2><h3>分析のためのデータの準備</h3><p>この分析のために、価格、携帯電話の仕様、購入者の人口統計、フィードバックを含む合成携帯電話販売データセットを生成しました。また、後でセマンティッククエリを実行できるように、ユーザーのフィードバックから埋め込みを生成しました。Elasticsearch ですぐに使用できる<a href="https://huggingface.co/intfloat/multilingual-e5-small">多言語 e5 小型モデル</a>を使用しました。</p><p></p><p>このデータセットを Elasticsearch で使用するには:</p><ol><li><p>Kibana の データファイルアップロード 機能を使用して、CSV ファイル<a href="https://www.elastic.co/docs/manage-data/ingest/upload-data-files"> (</a><a href="https://github.com/Alex1795/significant_terms_blog_dataset/blob/main/phone_sales_analysis_dataset.csv"> ここ</a> からダウンロード可能) をアップロードします。</p></li><li><p><a href="https://www.elastic.co/search-labs/blog/chat-with-pdf-elastic-playground#upload-pdfs-to-kibana">このブログ</a>で紹介されている「埋め込み」と呼ばれるセマンティックフィールドを設定します。 <code>multilingual-e5-small model</code></p></li><li><p>フィールド タイプのデフォルト ( <code>purchase_date</code>と<code>user_feedback)</code>を除くすべてのフィールドのキーワード) を使用してインポートを終了します。ここで提示されたクエリをそのまま実行できるようにするには、インデックス名<code>phone_sales_analysis</code>を必ず追加してください。</p></li></ol><p>この分析の主な焦点は、 <em><strong>「iPhone 16 の購入者と他の人口セグメントの違いは何か</strong></em>」を発見し、マーケティング目的で購入者をセグメント化することです。</p><p>これはデータセットからのサンプルドキュメントです。</p>{
         "customer_type": "Returning",
         "user_feedback": "I have to say, quality is great for the price. The battery life is really good.",
         "upgrade_frequency": "2 years",
         "storage_capacity": "256GB",
         "occupation": "Technology &amp; Data",
         "color": "Phantom Black",
         "gender": "Male",
         "price_paid": 899,
         "previous_brand_loyalty": "Mixed",
         "location_type": "Urban",
         "phone_model": "Samsung Galaxy S24",
         "city_region": "San Francisco Bay Area",
         "@timestamp": "2024-03-15T00:00:00.000-05:00",
         "income_bracket": "75000-100000",
         "purchase_channel": "Online",
         "feedback_sentiment": "positive",
         "education_level": "Bachelor",
         "embedding": "I have to say, quality is great for the price. The battery life is really good.",
         "customer_id": "C001",
         "purchase_date": "2024-03-15",
         "age": 34,
         "trade_in_model": "iPhone 13"
}<h3>人口動態パターンの理解</h3><p>ここでは、一般人口を対象に分析を実行し、iPhone 16 ユーザーにとって重要な用語の集計から得られた興味深い結果と比較します。</p><h4>通常のパターン</h4><p>通常の購入パターンを理解するために、さまざまなフィールドにわたるすべてのドキュメントのデータを集計できます。簡単にするために、携帯電話を購入した人の職業に焦点を当てて調査します。Elasticsearch へのリクエストでこれを実行できます。</p>GET phone_sales_analysis/_search
{
 "aggs": {
   "occupation_distribution": {
     "terms": {
       "size": 5,
       "field": "occupation"
     }
   }
 },
 "size": 0
}<p>これにより、データセット内の主な職業（レコード数別）は次のようになります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltec11e3ae5b9cb3c0/6a17f5d9505ac3f28aad8cba/99136ddddd7abad5d74481158a04501b6915441b-1518x480.png" alt="" /><h4>iPhone 16ユーザーのパターン</h4><p>iPhone 16 を購入した人々の違いを理解するために、次のように、クエリ内の人々を見つけるためのフィルターを使用して、同じフィールドで用語の集計を実行してみましょう。</p>GET phone_sales_analysis/_search
{
  "query": {
    "term": {
      "phone_model": "iPhone 16"
    }
  },
  "aggs": {
    "occupation_distribution": {
      "terms": {
        "size": 5,
        "field": "occupation"
      }
    }
  },
  "size": 0
}<p>つまり、iPhone 16ユーザーの主な職業は次のようになります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt26a5415e2f30d164/6a17f5da445de9637a4d028a/36ce86475beb03810c6ad81d7c776d1eec736654-1500x484.png" alt="" /><p>iPhone 16 ユーザーは、他の電話モデルのユーザーと比べて、使用パターンが異なっていることがわかります。Kibana を使用して結果を簡単に視覚化してみましょう。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e0ddb09fe58e454/6a17f5dce317912cfa2d596b/b70ab05bc962a274e1617b6caf20575c489a62d8-1448x1128.png" alt="" /><p></p><p>このグラフでは、iPhone 16 の傾向が全体の傾向と異なることがわかります。</p><p>この分析全体をスキップして、1つの重要な用語の集計を実行することで、iPhone 16ユーザーが一般ユーザーと何が違うのかを確認できます。</p>GET phone_sales_analysis/_search
{
  "query": {
    "term": {
      "phone_model": "iPhone 16"
    }
  },
  "aggs": {
    "occupation_distribution": {
      "significant_terms": {
        "size": 5,
        "field": "occupation"
      }
    }
  },
  "size": 0
}<p>つまり、次のような応答が得られます。</p><p>iPhone 16の職業の価値</p><p>ドキュメント数</p><p>bg_count</p><p>職業分布（最上位レベル）</p><p>122</p><p>424</p><p>医療・ヘルスケア分野</p><p>45</p><p>57</p><p>この回答は、iPhone 16 ユーザーが珍しい (つまり重大な) 状況にあることを明確に示しています。一般人口と比較した医療・ヘルスケア分野に従事する人の数。応答内の数字が何を意味するか見てみましょう。</p><ul><li><p><strong>最上位レベル:</strong></p><ul><li><p><strong>doc_count: 122 —</strong>クエリは合計122の文書と一致しました</p></li><li><p><strong>bg_count: 424 —</strong>背景セット（すべての販売文書）には424の文書が含まれています</p></li></ul></li><li><p><strong>医療・ヘルスケア分野:</strong></p><ul><li><p><strong>doc_count: 45 —</strong> 122件の検索結果のうち45件に「医療とヘルスケア」が出現</p></li><li><p><strong>bg_count: 57 —</strong>背景データセット内の合計424の文書のうち57に「医療とヘルスケア」が出現します</p></li></ul></li></ul><p>424 人の購入者のうち 57 人が医療・ヘルスケア分野で働いており、割合は 13.44% です。しかし、iPhone 16の購入者を見てみると、122人中45人が医療・ヘルスケア分野で働いており、その割合は36.88%です。つまり、iPhone 16 ユーザーの中に医療・ヘルスケアの分野で働く人がいる可能性が 2 倍になるということです。</p><p>同じ分析を他のフィールド（年齢、場所、収入層など）に適用すると、iPhone 16 ユーザーの独自性に関する詳細な情報を見つけることができます。</p><h3>消費者セグメンテーション</h3><p>重要な用語の集約を使用して、製品、カテゴリ、顧客セグメント間の関係性の洞察を抽出できます。このため、調査したいカテゴリの親集計を構築します。また、重要な用語と通常の用語のサブ集計を使用して、そのカテゴリに関する興味深い洞察を見つけ、その職業のほとんどの人が使用する用語と比較します。</p><p>たとえば、いくつかの職種の人々が何を好むかを見てみましょう。</p><ol><li><p>分析をより明確にするために、検索を3つの職種に限定してみましょう: [「管理・サポート」、「テクノロジー・データ」、「医療・ヘルスケア」]</p></li><li><p>集計側では、職業別の用語集計から始めます。</p></li><li><p>サブ集計を1つ追加します: 電話モデル別の用語 - 各分野のユーザーがどのモデルを購入しているかを調べます</p></li><li><p>2番目のサブ集計を追加します: 電話モデル別の重要な用語 - 各作業分野でどのモデルが特別であるかを見つけます</p></li></ol>GET phone_sales_analysis/_search
{
 "query": {
   "terms": {
     "occupation": [
       "Administrative &amp; Support",
       "Technology &amp; Data",
       "Medical &amp; Healthcare"
     ]
   }
 },
 "aggs": {
   "occupations": {
     "terms": {
       "size": 15,
       "field": "occupation"
     },
     "aggs": {
       "general_models": {
         "terms": {
           "field": "phone_model"
         }
       },
       "significant_models": {
         "significant_terms": {
           "field": "phone_model"
         }
       }
     }
   }
 },
 "size": 0
}<p>集計結果を詳しく見てみましょう。</p><p><strong>職業</strong>：管理・サポート</p><p><strong>用語の集約</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3a325cde37b40504/6a17f5dd4b055dbb68432372/a4ad519c9013867a3f4cee032160eadd8a47804a-1506x398.png" alt="" /><p><strong>重要な用語の集約</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltef514b8bbb7f429c/6a17f5df3e9e456488ba1612/e5604fa8036667bdfe733576a5e7c6153760dd3a-306x220.png" alt="" /><p>この表から、この職業の傾向と人口全体の傾向の間には大きな違いがないことが推測できます。</p><p><strong>職業</strong>：テクノロジー＆データ</p><p><strong>用語の集約</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt94189446d8f3100e/6a17f5e142022983b029f76e/13b09039bb7d183276451007d2d69dc190b1d3c0-1508x836.png" alt="" /><p></p><p><strong>重要な用語の集約</strong></p><p>合計文書数: 424</p><p>この職業に関する文書: 71</p><p>携帯電話のモデル</p><p>ドキュメント数 （この職業のこのモデル）</p><p>bg_count （すべての文書でこのモデルを使用）</p><p>すべての文書の%</p><p>この職業における%</p><p>グーグルピクセル8</p><p>12</p><p>22</p><p>5.19%</p><p>16.90%</p><p>ワンプラス11</p><p>9</p><p>14</p><p>3.30%</p><p>12.68%</p><p>ワンプラス 12 プロ</p><p>3</p><p>3</p><p>0.71%</p><p>4.23%</p><p>Google Pixel 8 Pro</p><p>9</p><p>21</p><p>4.95%</p><p>12.68%</p><p>何もない電話2</p><p>5</p><p>8</p><p>1.89%</p><p>7.04%</p><p>サムスン ギャラクシー Z フォールド5</p><p>4</p><p>6</p><p>1.42%</p><p>5.63%</p><p>ワンプラス12</p><p>8</p><p>20</p><p>4.72%</p><p>11.27%</p><p><strong>職業</strong>：医療・ヘルスケア</p><p><strong>用語の集約</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt270b0a861a16488a/6a17f5e23e03d76a934f2df0/b008e996742fc0bb48dc6bacff17cfbc56cf0d73-1492x398.png" alt="" /><p><strong>重要な用語の集約</strong></p><p>合計文書数: 424</p><p>この職業に関する文書: 57</p><p>携帯電話のモデル</p><p>ドキュメント数 （この職業のこのモデル）</p><p>bg_count （すべての文書でこのモデルを使用）</p><p>すべての文書の%</p><p>この職業における%</p><p>iPhone 16</p><p>45</p><p>122</p><p>28.77%</p><p>78.95%</p><p>iPhone 15 Pro Max</p><p>3</p><p>13</p><p>3.07%</p><p>5.26%</p><p>iPhone 15</p><p>7</p><p>40</p><p>9.43%</p><p>12.28%</p><p>このデータが何を伝えているのか見てみましょう。</p><ul><li><p>医療およびヘルスケアの専門家は iPhone 16 を好み、一般的に Apple の携帯電話を使用する傾向が非常に強いです。</p></li><li><p>テクノロジーおよびデータの専門家はハイエンドの Android スマートフォンを好みますが、必ずしも Samsung ブランドを使用するわけではありません。このカテゴリーでは、iPhone にもかなりのトレンドが見られます。</p></li><li><p>管理およびサポート担当者は Samsung や Google の携帯電話を好みますが、明確な独自の傾向はありません。</p></li></ul><h3>重要語の集約とハイブリッド検索</h3><p>ハイブリッド検索は、テキスト検索とセマンティック結果を組み合わせて、検索エクスペリエンスを向上させます。この文脈において、重要な用語の集約は<strong>、「このデータセットは他のすべての文書と比べて何が特別なのか？」</strong>という問いに答えることで、コンテキスト認識検索の結果に関する洞察を提供することができます。この機能を示すために、ユーザーが優れたパフォーマンスについて語る際に、どのモデルが過剰に表現されているかを見てみましょう。 </p><ul><li><p>フィールド埋め込みよりも入力「良いパフォーマンス」に近いトップユーザーフィードバックを見つけるセマンティッククエリを構築してみましょう。</p></li><li><p>テキストフィールドuser_feedbackで同じ用語を使ったテキスト検索も使用します。</p></li><li><p>また、完全なデータセットよりもこれらの結果の中でより頻繁に見つかる電話モデルを見つけるために、重要な用語クエリを追加します。
</p></li></ul>GET phone_sales_analysis/_search
{
 "retriever": {
   "rrf": {
     "retrievers": [
       {
         "standard": {
           "query": {
             "bool": {
               "must": [
                 {
                   "match": {
                     "user_feedback": {
                       "query": "good performance",
                       "operator": "and"
                     }
                   }
                 }
               ]
             }
           }
         }
       },
       {
         "standard": {
           "query": {
             "semantic": {
               "field": "embedding",
               "query": "good performance"
             }
           }
         }
       }
     ],
    "rank_window_size": 20
   }
 },
 "aggs": {
   "Models": {
     "significant_terms": {
       "field": "phone_model"
     }
   }
 }
}<p>一致するドキュメントの例を見てみましょう。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1c3dc221896c8832/6a17f5e4445de91eac4d028e/4cb488097a382f0c28c21540db4f593d23633473-1600x162.png" alt="" /><p>返ってくる応答は次のとおりです。</p>{
  "took": 388,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 20,
      "relation": "eq"
    },
    "max_score": 0.016393442,
    "hits": [...]
  },
  "aggregations": {
    "Models": {
      "doc_count": 20,
      "bg_count": 424,
      "buckets": [
        {
          "key": "iPhone 15",
          "doc_count": 5,
          "score": 0.4125,
          "bg_count": 40
        }
      ]
    }
  }
}<p></p><p>これは、iPhone 15 が合計 424 のドキュメントのうち 40 回 (ドキュメントの 9.4%) 出現している一方で、セマンティック検索「良好なパフォーマンス」に一致した 20 のドキュメント (ドキュメントの 25%) では 5 回見つかるということを示しています。したがって、次のような結論を導き出すことができます。優れたパフォーマンスについて話しているときに、偶然よりも iPhone 15 が見つかる可能性が 2.7 倍高くなります。</p><h2>まとめ</h2><p>重要な用語の集約により、データセットをドキュメント全体と比較することで、データセットの固有の詳細を明らかにすることができます。これにより、発生回数を超えて、データ内の予期しない関係が明らかになる可能性があります。さまざまなユースケースで重要な用語を適用して、非常に興味深い機能を実現できます。たとえば、次のようになります。</p><ul><li><p><a href="https://www.elastic.co/blog/significant-terms-aggregation#credit">不正行為検出に取り組む際にパターンを見つけ</a>、盗難されたクレジットカードの一般的な取引を識別します。</p></li><li><p>ユーザーレビューからのブランド品質の洞察 - 悪いレビューの数が不釣り合いに多いブランドを検出します。</p></li><li><p>誤分類されたドキュメントの<a href="https://www.elastic.co/docs/reference/aggregations/search-aggregations-bucket-significantterms-aggregation#_use_on_free_text_fields">検出</a>- 説明にそのカテゴリに一般的でない単語を使用しているカテゴリ (用語フィルター) に属するドキュメントを検出します (重要な用語の集約)。</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/significant-terms-aggregation-elasticsearch</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/significant-terms-aggregation-elasticsearch</guid>
    <category><![CDATA[基本]]></category>
    <category><![CDATA[Query DSL]]></category>
    <dc:creator><![CDATA[Alexander Dávila]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta4d95b6134c2a110/6a17f5e6505ac3fd3cad8cbf/13adbc901837835bb56abf15e377127b017cfac8-1536x1024.png" length="0" type="image/png"/>
    <pubDate>Mon, 07 Jul 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[GCP GKE AutopilotでElasticsearchをデプロイする方法]]></title>
    <description><![CDATA[部分的に管理されたElasticsearchセットアップ構成のために、GKEオートパイロットとECKを使用してElasticsearchクラスターをGCPにデプロイする方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>この記事では、Autopilotを使用してGoogle Cloud Kubernetes（GKE）にElasticsearchをデプロイする方法を学びます。</p><p>Elasticsearchでは、<a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud on Kubernetes</a>（ECK）を使用します。これはElasticsearch Kubernetes公式オペレーターであり、すべてのElastic StackコンポーネントのKubernetes導入のオーケストレーションを簡素化します。</p><p>ElasticsearchクラスターをさまざまなGCPインフラストラクチャーにデプロイする方法の詳細は、<a href="https://www.elastic.co/search-labs/blog/elasticsearch-gpc-google-compute-engine">Google Cloud Compute</a>と<a href="https://www.elastic.co/search-labs/blog/deploy-elastic-gcp-marketplace">Google Cloud Marketplace</a>の入門記事をご覧ください。</p><h2>Elasticsearchの導入作業</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt61969357430c94f8/6a17f6d125daab024708a3ae/56b54d718dcff9af9050873c41fdf738074851da-1428x582.png" alt="Elasticsearch ECKの導入作業。" /><h3>GKE Autopilotとは何ですか？</h3><p><a href="https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview?hl=es-419"><strong>Google Kubernetes Engine（GKE）Autopilot</strong></a>は、Googleがクラスター設定、ノード管理、セキュリティ、スケーリングを処理し、開発者がアプリケーションのデプロイに集中できる、完全に管理されたKubernetesエクスペリエンスを提供します。これにより、チームは組み込まれたベストプラクティスを使用し、コードから本番環境まで数分で移行できます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt91e10f44290aeac4/6a17f6d33e9e451f67ba1638/bbf6de63fa0a199326352f521cb22654818799f6-1600x958.png" alt="GKE Autopilot コンテナ。" /><h2>Google CloudでECKを使用するタイミングは？</h2><p>Elastic Cloud on Kubernetes（ECK）は、既存のKubernetesインフラを持つ組織が、専用ノードロール、高可用性、自動化などの高度な機能を備えたElasticsearchをデプロイするのに最適です。</p><h2>Google CloudでECKを設定する方法は？</h2><p>1. <a href="https://console.cloud.google.com">Google Cloud Console</a>にログインします。</p><p>2. <strong>右上</strong>の<strong>Cloud Shell</strong>ボタンをクリックし、コンソールにアクセスして、そこから GKEクラスターをデプロイします。あるいは、<a href="https://cloud.google.com/cli">gcloud CLI</a>を使用することもできます。</p><p><em><strong>チュートリアルでは、必ずプロジェクトIDを自分のプロジェクトIDに更新してください。</strong></em></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc69e47bf97e4be31/6a17f6d5505ac3bbe6ad8cdb/999b03861d4fe44f360ab4c7e2616e1dc10cf182-1558x1248.png" alt="GCP GKE AutopilotでElasticsearchを設定する方法。" /><p>3. <a href="https://console.cloud.google.com/flows/enableapi?apiid=container.googleapis.com">Google Kubernetes Engine API</a>を有効にします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1a4d95465f563ece/6a17f6d7e8fbced6393a1af3/03827d3dc0e987c019e7747d33e7c01920047beb-911x246.png" alt="Google Kubernetes Engine APIの有効化。" /><p><em><strong>[次へ]</strong></em> をクリックします。</p><p>これで、Kubernetes Engine APIを検索すると、Kubernetes Engine APIが有効になっていることが表示されます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6ba41b82d995347f/6a17f6d8505ac3036bad8cdf/d5cd46f0333086bcb31b80cf9c08a469b449ec0f-640x250.png" alt="Kubernetes Engine API。" /><p>4. Cloud ShellでAutopilotクラスターを作成します。これをautopilot-cluster-1という名前にし、autopilot-testをプロジェクトのIDに置き換えます。</p>gcloud beta container --project "autopilot-test-457216" clusters create-auto "autopilot-cluster-1" --region "us-central1" --release-channel "regular" --tier "standard" --enable-ip-access --no-enable-google-cloud-access --network "projects/autopilot-test-457216/global/networks/default" --subnetwork "projects/autopilot-test-457216/regions/us-central1/subnetworks/default" --cluster-ipv4-cidr "/17" --binauthz-evaluation-mode=DISABLED<p>5. 準備ができるまで待ちます。作成には10分ほどかかります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4e821e77d5db5d71/6a17f6da148009381cb48900/81fbc45ba56d0f16ba42724cb8ae45e60b327dbc-1581x258.png" alt="Autopilotクラスターのセットアップの画像。" /><p>クラスターを正しく設定すると確認メッセージが表示されます。</p><p>6. kubectlコマンドラインアクセスを設定します。</p>gcloud container clusters get-credentials autopilot-cluster-1 --region us-central1 --project autopilot-test-457216<p>次のように表示されます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltf1c828e5059c8ec8/6a17f6dcabe0f215e5dfebb7/b0beba1ee00ce9029f586ee32693fc2aa58c7f65-3442x142.png" alt="" /><p><em>autopilot-cluster-1用に生成されたkubeconfigエントリ。</em></p><p>7. <a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud on Kubernetes</a>（ECK）オペレーターをインストールします。</p># Install ECK Custom Resource Definitions
kubectl create -f https://download.elastic.co/downloads/eck/2.16.1/crds.yaml

# Install the ECK operator
kubectl apply -f https://download.elastic.co/downloads/eck/2.16.1/operator.yaml<p>8. デフォルト値で単一ノードのElasticsearchインスタンスを作成しましょう。</p><p>異なる設定のレシピを確認したい場合は<a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/recipes">こちらのリンク</a>をご覧ください。</p><p><code>storageClass</code>を指定しない場合、ECKはデフォルトで設定されたものを使用します。GKEの場合は<code>standard-rwo</code>で、これは<a href="https://cloud.google.com/kubernetes-engine/docs/how-to/persistent-volumes/gce-pd-csi-driver?cloudshell=true">Compute Engine persistent disk CSI Driver</a>を使用して1GBのボリュームを作成します。</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 9.0.0
  nodeSets:
  - name: default
    count: 1
    config:
      node.store.allow_mmap: false
EOF<p>デフォルトの GKE マシンの<code>vm.max_map_count</code>値が低すぎるため、 <code>nmap</code>を無効にしました。本番環境ではこれを無効にせず、 <code>vm.max_map_count</code>の値を増やすことが推奨されます。詳しくは<a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/virtual-memory">こちら</a>をご覧ください。</p><p>9. Kibanaのシングルノードクラスターもデプロイしましょう。Kibanaの場合、デバイスからKibanaにアクセスするために使用できる外部IPを提供するLoadBalancerを追加します。</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: quickstart
spec:
  version: 9.0.0
  http:
    service:
      metadata:
        annotations:
          cloud.google.com/l4-rbs: "enabled"
      spec:
        type: LoadBalancer
  count: 1
  elasticsearchRef:
    name: quickstart
EOF<p>注釈に注意してください。 </p><p><code>cloud.google.com/l4-rbs: "enabled"</code></p><p><em><strong>これは、Autopilotにパブリック向けのLoadBalancerを提供するように指示するため、非常に重要です。設定しない場合、LoadBalancerは内部になります。</strong></em></p><p>10. ポッドが動作していることを確認します。</p>kubectl get pods<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt627dd8f482340bc2/6a17f6de3e03d779a44f2e16/99da1270581a137683770efdb9c6e1577ec9fc01-3150x442.png" alt="" /><p>11. また、<code>run kubectl get elasticsearch</code>と<code>kubectl get kibana</code>することで、Elasticsearchのバージョン、ノード、健全性などのより具体的な統計情報を取得することもできます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt32d179d1c4f785b3/6a17f6e04b055db05a432392/86234f307970fd5f78b8acd41496e8cc89ff82d3-3414x326.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt75b60dc0e4ad9636/6a17f6e296142a27eaeb1ca6/29160286ccc88928734c8ea11b1923db8e85d49d-3142x318.png" alt="" /><p>12. サービスにアクセスします。</p>kubectl get svc<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3806ad91791373a2/6a17f6e46df731bc800a10ab/ed1a07314b84a99b4aa1fec3db4b9badeb9587ee-3446x610.png" alt="" /><p>これにより、EXTERNAL-IPのKibanaの外部URLが表示されます。LoadBalancerの提供には数分かかる場合があります。<em><strong>EXTERNAL-IPの値をコピーします。</strong></em></p><p>13 「elastic」ユーザーのElasticsearchパスワードを取得します。</p>kubectl get secret quickstart-es-elastic-user -o=jsonpath='{.data.elastic}' | base64 --decode<img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5ab53ce5a685491b/6a17f6e63e03d74fcc4f2e1a/ab5054219216ebc15fc0d96e27605aaf13b720c6-3448x210.png" alt="" /><p>14. ブラウザから<strong>Kibana にアクセス</strong>します。</p><ul><li><p>URL: https://&lt;EXTERNAL_IP&gt;:5601</p></li><li><p>ユーザー名:elastic</p></li><li><p>パスワード:28Pao50lr2GpyguX470L2uj5（前のステップから）</p></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd86d22f797132c21/6a17f6e7e8fbce62b43a1afb/47cbe88dc14db64db3a256f3f7504cc86a843475-463x503.png" alt="Elasticウェルカム画面。" /><p>15. ブラウザからアクセスすると、ウェルカム画面が表示されます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt6f44dc23e6f1f625/6a17f6e9be6086ea71004948/a75c151c0144b7efe2b730698c0ed0156fa9b16a-1600x1005.png" alt="Elasticsearchのホームページです。" /><p>ノードの変更やサイズ変更など、Elasticsearchクラスターの仕様を変更したい場合は、新しい設定でymlマニフェストを再度適用できます。</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: elasticsearch.k8s.elastic.co/v1
kind: Elasticsearch
metadata:
  name: quickstart
spec:
  version: 9.0.0
  nodeSets:
    - name: default
      count: 2
      config:
        node.store.allow_mmap: false
      podTemplate:
        spec:
          containers:
            - name: elasticsearch
              resources:
                requests:
                  memory: 1.5Gi
                  cpu: 2
                limits:
                  memory: 1.5Gi
                  cpu: 2
EOF<p>この例では、ノードをもう1つ追加して、RAMとCPUを変更します。ご覧のとおり、 <code>kubectl get elasticsearch</code>には2つのノードが表示されています。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt33a7ba0be483195a/6a17f6ebe8fbcea7da3a1aff/48b475622cc48890bff8105d151f2cbde28d7021-3418x298.png" alt="" /><p>Kibanaにも同じことが当てはまります。</p>cat &lt;&lt;EOF | kubectl apply -f -
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: quickstart
spec:
  version: 9.0.0
  http:
    service:
      metadata:
        annotations:
          cloud.google.com/l4-rbs: "enabled"
      spec:
        type: LoadBalancer
  count: 1
  elasticsearchRef:
    name: quickstart
  podTemplate:
    spec:
      containers:
        - name: kibana
          env:
            - name: NODE_OPTIONS
              value: "--max-old-space-size=1024"
          resources:
            requests:
              memory: 0.5Gi
              cpu: 0.5
            limits:
              memory: 1Gi
              cpu: 1
EOF<p>コンテナのCPU/RAMと<a href="https://nodejs.org/">Node.js</a>のメモリ使用量（<a href="https://nodejs.org/api/cli.html#--max-old-space-sizesize-in-mib">max-old-space-size</a>）を調整できます。</p><p><a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s/volume-claim-templates">既存のボリュームクレームを縮小することはできない</a>ことに留意してください。アップデートを適用した後、オペレーターは最小限の中断時間で変更を加えます。</p><p>不要なコストを避けるために、テストが完了したらクラスターを忘れずに削除してください。</p>gcloud container clusters delete autopilot-cluster-1<h2>今後の見通し</h2><p>KubernetesとGoogle Kubernetes Engineについて詳しく知りたい場合は、次の記事をご覧ください。</p><ul><li><p><a href="https://www.elastic.co/docs/deploy-manage/deploy/cloud-on-k8s">Elastic Cloud on Kubernetes | Elastic Docs</a></p></li><li><p><a href="https://cloud.google.com/blog/products/containers-kubernetes/introducing-gke-autopilot">GKE Autopilotのご紹介 | Google Cloudブログ</a></p></li><li><p><a href="https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview">Autopilotの概要 | Google Kubernetes Engine（GKE）</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/eck-gke-autopilot</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/eck-gke-autopilot</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Eduard Martin]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltea045d2d12606d11/6a17f6edb1e113c86179f3e7/d9c462fe63011356671479ccfedd435eec1ede52-1200x628.png" length="0" type="image/png"/>
    <pubDate>Thu, 19 Jun 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[JavaScript で Elasticsearch を正しく使う方法、パート II]]></title>
    <description><![CDATA[本番環境でのベストプラクティスと、コーディングエラーを減らすためにServerless環境でElasticsearch Node.jsクライアントを実行する方法についてご覧ください。 ]]></description>
    <content:encoded><![CDATA[<p>これは、JavaScript での Elasticsearch シリーズの第 2 部です。<a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i">最初の部分では、</a>環境を正しくセットアップし、Node.js クライアントを構成し、データをインデックスして検索する方法を学びました。この第 2 部では、実稼働のベスト プラクティスを実装し、サーバーレス環境で Elasticsearch <a href="http://node.js">Node.js</a>クライアントを実行する方法を学習します。</p><p>以下を確認します:</p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#production-best-practices">制作のベストプラクティス</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#error-handling">エラー処理</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#testing">テスト</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#serverless-environments">サーバーレス環境</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#running-the-client-on-elastic-serverless">Elastic Serverlessでクライアントを実行する</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii#running-the-client-on-function-as-a-service-environment">Function-as-a-Service 環境でクライアントを実行する</a></p></li></ul></li></ul><p><a href="https://github.com/Delacrobix/JS-client-best-practices_article"><em><strong>ここで</strong></em></a><em> 例付きのソースコードを確認できます</em><em><strong> 。</strong></em></p><h2>制作のベストプラクティス</h2><h3>Elasticsearchにおけるエラー処理。</h3><p>Node.js の Elasticsearch クライアントの便利な機能は、Elasticsearch で発生する可能性のあるエラーのオブジェクトを公開し、さまざまな方法で検証して処理できることです。</p><p><a href="https://www.elastic.co/docs/reference/elasticsearch/clients/javascript/connecting#client-error-handling">すべてを表示する</a>には、次のコマンドを実行します。</p>const { errors } = require('@elastic/elasticsearch')
console.log(errors)<p>検索の例に戻り、起こりうるエラーのいくつかを処理してみましょう。</p>app.get("/search/lexic", async (req, res) =&gt; {
 ....
  } catch (error) {
    if (error instanceof errors.ResponseError) {
      let errorMessage =
        "Response error!, query malformed or server down, contact the administrator!";

      if (error.body.error.type === "parsing_exception") {
        errorMessage = "Query malformed, make sure mappings are set correctly";
      }

      res.status(error.meta.statusCode).json({
        erroStatus: error.meta.statusCode,
        success: false,
        results: null,
        error: errorMessage,
      });
    }

    res.status(500).json({
      success: false,
      results: null,
      error: error.message,
    });
  }
});<p><code>ResponseError</code> 特に、回答が<code>4xx</code>または<code>5xx</code>場合に発生します。これは、要求が正しくないか、サーバーが利用できないことを意味します。</p><p>このタイプのエラーは<strong>、テキストタイプのフィールドで用語クエリを実行するなど、間違ったクエリを生成することでテストできます。</strong></p><p>デフォルトエラー:</p> {
    "success": false,
    "results": null,
    "error": "parsing_exception\n\tRoot causes:\n\t\tparsing_exception: [terms] query does not support [visit_details]"
}<p>カスタマイズされたエラー: </p>{
    "erroStatus": 400,
    "success": false,
    "results": null,
    "error": "Response error!, query malformed or server down; contact the administrator!"
}<p>各タイプのエラーを特定の方法でキャプチャして処理することもできます。たとえば、 <code>TimeoutError</code>に再試行ロジックを追加できます。</p>app.get("/search/semantic", async (req, res) =&gt; {
    try {
  ...
  } catch (error) {
    if (error instanceof errors.TimeoutError) {


     // Retry logic...

      res.status(error.meta.statusCode).json({
        erroStatus: error.meta.statusCode,
        success: false,
        results: null,
        error:
          "The request took more than 10s after 3 retries. Try again later.",
      });
    }
  }
});<h3>テスト</h3><p>テストはアプリの安定性を保証する上で重要です。Elasticsearch から分離された方法でコードをテストするには、クラスターを作成するときにライブラリ<a href="https://github.com/elastic/elasticsearch-js-mock">elasticsearch-js-mock を</a>使用できます。</p><p>このライブラリを使用すると、実際のクライアントと非常によく似たクライアントをインスタンス化できますが、クライアントの HTTP レイヤーのみをモックのレイヤーに置き換え、残りは元のレイヤーと同じにすることで、構成に応答します。</p><p>自動テスト用に、モック ライブラリと<a href="https://github.com/avajs/ava">AVA</a>をインストールします。</p><p><code>npm install @elastic/elasticsearch-mock</code></p><p><code>npm install --save-dev ava</code></p><p>テストを実行するために<code>package.json</code>ファイルを構成します。次のようになっていることを確認してください:</p>"type": "module",
	"scripts": {
		"test": "ava"
	},
	"devDependencies": {
		"ava": "^5.0.0"
	}<p>それでは、 <code>test.js</code>ファイルを作成し、モッククライアントをインストールしましょう。</p>const { Client } = require('@elastic/elasticsearch')
const Mock = require('@elastic/elasticsearch-mock')

const mock = new Mock()
const client = new Client({
  node: 'http://localhost:9200',
  Connection: mock.getConnection()
})<p>次に、セマンティック検索のモックを追加します。</p>function createSemanticSearchMock(query, indexName) {
  mock.add(
    {
      method: "POST",
      path: `/${indexName}/_search`,
      body: {
        query: {
          semantic: {
            field: "semantic_field",
            query: query,
          },
        },
      },
    },
    () =&gt; {
      return {
        hits: {
          total: { value: 2, relation: "eq" },
          hits: [
            {
              _id: "1",
              _score: 0.9,
              _source: {
                owner_name: "Alice Johnson",
                pet_name: "Buddy",
                species: "Dog",
                breed: "Golden Retriever",
                vaccination_history: ["Rabies", "Parvovirus", "Distemper"],
                visit_details:
                  "Annual check-up and nail trimming. Healthy and active.",
              },
            },
            {
              _id: "2",
              _score: 0.7,
              _source: {
                owner_name: "Daniel Kim",
                pet_name: "Mochi",
                species: "Rabbit",
                breed: "Mixed",
                vaccination_history: [],
                visit_details:
                  "Nail trimming and general health check. No issues.",
              },
            },
          ],
        },
      };
    }
  );
}<p>これで、コードのテストを作成し、Elasticsearch 部分が常に同じ結果を返すことを確認できるようになりました。</p>import test from 'ava';

test("performSemanticSearch must return formatted results correctly", async (t) =&gt; {
  const indexName = "vet-visits";
  const query = "Which pets had nail trimming?";

  createSemanticSearchMock(query, indexName);

  async function performSemanticSearch(esClient, q, indexName = "vet-visits") {
    try {
      const result = await esClient.search({
        index: indexName,
        body: {
          query: {
            semantic: {
              field: "semantic_field",
              query: q,
            },
          },
        },
      });

      return {
        success: true,
        results: result.hits.hits,
      };
    } catch (error) {
      if (error instanceof errors.TimeoutError) {
        return {
          success: false,
          results: null,
          error: error.body.error.reason,
        };
      }

      return {
        success: false,
        results: null,
        error: error.message,
      };
    }
  }

  const result = await performSemanticSearch(esClient, query, indexName);

  t.true(result.success, "The search must be successful");
  t.true(Array.isArray(result.results), "The results must be an array");

  if (result.results.length &gt; 0) {
    t.true(
      "_source" in result.results[0],
      "Each result must have a _source property"
    );
    t.true(
      "pet_name" in result.results[0]._source,
      "Results must include the pet_name field"
    );
    t.true(
      "visit_details" in result.results[0]._source,
      "Results must include the visit_details field"
    );
  }
});<p>テストを実行してみましょう。</p><p><code>npm run test</code></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt36304e286146f362/6a170559d7c02237b2de638f/42feae845ae8eae03c37ad7ad114e8db35984812-1186x302.png" alt="" /><p>完了です！これからは、外部要因ではなくコードに100%重点を置いてアプリをテストできます。</p><h2>サーバーレス環境</h2><h3>Elastic Serverlessでクライアントを実行する方法</h3><p>クラウドまたはオンプレミスでの Elasticsearch の実行について説明しましたが、Node.js クライアントは<a href="https://www.elastic.co/guide/en/serverless/current/intro.html">Elastic Cloud Serverless</a>への接続もサポートしています。</p><p>Elastic Cloud Serverless を使用すると、Elastic がインフラストラクチャを内部で処理するためインフラストラクチャについて心配する必要がないプロジェクトを作成でき、インデックスを作成するデータとそのデータにアクセスする期間のみを考慮すれば済みます。</p><p>使用の観点から見ると、Serverless はコンピューティングとストレージを切り離し、<a href="https://www.elastic.co/search-labs/blog/elasticsearch-serverless-tier-autoscaling">検索</a>と<a href="https://www.elastic.co/search-labs/blog/elasticsearch-ingest-autoscaling">インデックス作成</a>の両方に自動スケーリング機能を提供します。これにより、実際に必要なリソースのみを増やすことができます。</p><p>クライアントは、Serverless に接続するために次の調整を行います。</p><ul><li><p>スニッフィングをオフにし、スニッフィング関連のオプションを無視します</p></li><li><p>最初のノードを除いて、config で渡されたすべてのノードを無視し、ノードのフィルタリングと選択のオプションも無視します。</p></li><li><p>圧縮と `TLSv1_2_method` を有効にします（Elastic Cloud 用に構成した場合と同じ）</p></li><li><p>すべてのリクエストに `elastic-api-version` HTTP ヘッダーを追加します</p></li><li><p>デフォルトでは `WeightedConnectionPool` ではなく `CloudConnectionPool` を使用します</p></li><li><p>標準の MIME タイプを優先して、ベンダーの `content-type` および `accept` ヘッダーをオフにします。</p></li></ul><p>サーバーレス プロジェクトを接続するには、パラメーター serverMode: serverless を使用する必要があります。</p>const { Client } = require('@elastic/elasticsearch')
const client = new Client({
  node: 'ELASTICSEARCH_ENDPOINT',
  auth: { apiKey: 'ELASTICSEARCH_API_KEY' },
  serverMode: "serverless",
});<h3>Function-as-a-Service環境でクライアントを実行する方法</h3><p>この例では Node.js サーバーを使用しましたが、AWS lambda、GCP Run などの機能を備えた Function-as-a-Service 環境を使用して接続することもできます。</p>'use strict'

const { Client } = require('@elastic/elasticsearch')

const client = new Client({
  // client initialisation
})

exports.handler = async function (event, context) {
  // use the client
}<p>もう 1 つの例は、同じくサーバーレスである Vercel などのサービスに接続することです。これを実行する方法の<a href="https://github.com/elastic/elasticsearch-js/blob/main/docs/examples/proxy/README.md">完全な例</a>を確認できますが、<a href="https://github.com/elastic/elasticsearch-js/blob/main/docs/examples/proxy/api/search.js">検索エンドポイント</a>の最も重要な部分は次のようになります。</p>const response = await client.search(
  {
    index: INDEX,
    // You could directly send from the browser
    // the Elasticsearch's query DSL, but it will
    // expose you to the risk that a malicious user
    // could overload your cluster by crafting
    // expensive queries.
    query: {
      match: { field: req.body.text },
    },
  },
  {
    headers: {
      Authorization: `ApiKey ${token}`,
    },
  }
);<p>このエンドポイントは /api フォルダーにあり、サーバー側から実行されるため、クライアントは検索用語に対応する「テキスト」パラメータのみを制御できます。</p><p>Function-as-a-Service を使用する意味は、24 時間 365 日稼働するサーバーとは異なり、関数は関数を実行するマシンのみを起動し、関数が終了するとマシンは休止モードになり、消費するリソースが少なくなることです。</p><p>この構成は、アプリケーションがあまり多くのリクエストを受け取らない場合には便利ですが、そうでない場合はコストが高くなる可能性があります。また、<a href="https://docs.aws.amazon.com/lambda/latest/dg/lambda-runtime-environment.html">関数のライフサイクル</a>と実行時間 (場合によっては数秒しかないこともあります) も考慮する必要があります。</p><h2>まとめ</h2><p>この記事では、実稼働環境で非常に重要なエラーの処理方法を学びました。また、Elasticsearch サービスをモックしながらアプリケーションをテストする方法についても説明しました。これにより、クラスターの状態に関係なく信頼性の高いテストが提供され、コードに集中できるようになります。</p><p>最後に、Elastic Cloud Serverless と Vercel アプリケーションの両方をプロビジョニングして、完全にサーバーレスなスタックを立ち上げる方法を示しました。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-ii</guid>
    <category><![CDATA[JavaScript]]></category>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Jeffrey Rengifo]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc58be329ffebcd60/6a17043e47d49c0bc62d88ab/70fb0ff949f6db9ac9b8a28ecb4329ab915ebf46-720x420.png" length="0" type="image/png"/>
    <pubDate>Mon, 19 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch のディスク容量と使用量を最適化する方法]]></title>
    <description><![CDATA[Elasticsearchのディスクの空き容量が極端に少ない場合（過度な利用）や、ディスク容量が十分に活用されていない場合を未然に防ぎ、対処する方法について知り、クラスターのコストを最適化します。]]></description>
    <content:encoded><![CDATA[<p>ディスク管理はどのデータベースでも重要であり、Elasticsearch も例外ではありません。十分なディスク容量がない場合、Elasticsearch はノードへのシャードの割り当てを停止します。これにより、最終的にはクラスターにデータを書き込むことができなくなり、アプリケーションでデータが失われる潜在的なリスクが生じます。一方、ディスク容量が多すぎる場合は、必要以上のリソースに対して料金を支払うことになります。</p><h2>透かしの背景</h2><p>Elasticsearch クラスターには、使用可能なディスク容量を追跡するのに役立つさまざまな「ウォーターマーク」しきい値があります。ノード上のディスクがいっぱいになると、最初に超えるしきい値は「低ディスク ウォーターマーク」になります。2 番目のしきい値は、「高ディスク ウォーターマークしきい値」になります。最終的には、「ディスク洪水段階」に到達します。このしきい値を超えると、クラスターは、ウォーターマークを通過したノード上の 1 つのシャード (プライマリまたはレプリカ) を持つすべてのインデックスへの書き込みをブロックします。読み取り（検索）は引き続き可能です。</p><h2>ディスクがいっぱいになった場合（過剰使用）の防止と対処方法</h2><p>Elasticsearch ディスクがいっぱいになった場合の対処方法はいくつかあります。</p><ol><li><p><strong>古いデータ を削除する:</strong> 通常、データを無期限に保存しないでください。ディスクがいっぱいになるのを防ぎ、解決する 1 つの方法は、データが一定の期間に達したときに確実にアーカイブされ、削除されるようにすることです。これを行う 1 つの方法は、 <a href="https://www.elastic.co/docs/manage-data/lifecycle/index-lifecycle-management">ILM を</a>使用することです。</p></li><li><p><strong>ストレージ容量の追加:</strong>データを削除できない場合は、パフォーマンスに悪影響を与えずにすべてのデータを保持するために、データ ノードを追加するか、ディスク サイズを増やす必要がある場合があります。クラスターにストレージ容量を追加する必要がある場合は、ストレージ容量だけを追加するのか、それともストレージ容量に加えて RAM と CPU のリソースも比例して追加するのかを検討する必要があります (以下の<a href="https://www.elastic.co/search-labs/blog/optimize-elasticsearch-disk-space-and-usage#the-relationship-between-disk-size,-ram-and-cpu">ディスク サイズ、RAM、CPU の比率</a>に関するセクションを参照)。</p></li></ol><h2>Elasticsearch クラスターにストレージ容量を追加する方法</h2><ol><li><p><strong>データ ノードの数を増やします。</strong>新しいノードは既存のノードと同じサイズで、同じ Elasticsearch バージョンである必要があることに注意してください。</p></li><li><p><strong>既存のノードのサイズを増やす:</strong>クラウドベースの環境では、通常、既存のノードのディスク サイズと RAM/CPU を増やすのは簡単です。</p></li><li><p><strong>ディスク サイズのみを増やす:</strong>クラウドベースの環境では、ディスク サイズを増やすのは比較的簡単です。</p></li><li><p><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"><strong>スナップショット</strong></a><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"> </a><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"><strong>そして</strong></a><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"> </a><a href="https://www.elastic.co/docs/deploy-manage/tools/snapshot-and-restore"><strong>復元</strong></a><strong>:</strong>要求に応じて古いデータを自動プロセスでバックアップから取得できるようにする場合は、古いインデックスのスナップショットを作成し、それらを削除して、要求に応じてスナップショットからデータを一時的に復元できます。</p></li><li><p><strong>シャードごとのレプリカの数を減らす:</strong>データを削減するもう 1 つのオプションは、各シャードのレプリカの数を減らすことです。高可用性を実現するには、シャードごとに 1 つのレプリカを用意する必要がありますが、データが古くなると、レプリカなしでも作業できる可能性があります。これは通常、データが永続的である場合、または必要に応じて復元できるバックアップがある場合に機能します。</p></li><li><p><strong>アラートを作成する:</strong>将来ディスクがいっぱいになるのを防ぎ、積極的に対処するには、ディスクの使用状況に基づいて、ディスクがいっぱいになり始めたときに通知するアラートを作成する必要があります。</p></li></ol><h2>ディスク容量が十分に活用されない場合の防止と対処方法</h2><p>ディスク容量が十分に活用されていない場合は、クラスター上のストレージ ボリュームを削減するさまざまなオプションがあります。</p><h3>Elasticsearch クラスターのストレージ容量を削減する方法</h3><p>クラスターのストレージ容量を削減する方法はさまざまです。</p><p><strong>1. データノードの数を減らす</strong></p><p>データストレージを削減し、RAM と CPU リソースも同じ割合で削減したい場合は、これが最も簡単な戦略です。不要なノードを廃止すると、最大のコスト削減が実現する可能性があります。</p><p>ノードを廃止する前に、次の操作を行う必要があります。</p><ul><li><p>廃止するノードが MASTER ノードとして必要ではないことを確認します。常に、MASTER ノード ロールを持つノードが少なくとも 3 つ必要です。</p></li><li><p>廃止するノードからデータ シャードを移行します。</p></li></ul><p><strong>2. 既存のノードを小さなノードに置き換える</strong></p><p>ノードの数をさらに減らすことができない場合 (通常、最小構成は 3 です)、既存のノードのサイズを縮小することが必要になる場合があります。シャードはノードあたりのシャード数に基づいてバランスが取られるため、すべてのデータ ノードが同じ RAM メモリとディスク サイズであることを確認することをお勧めします。</p><p>プロセスは次のようになります。</p><ul><li><p>クラスターに新しい小さなノードを追加する</p></li><li><p>廃止するノードからシャードを移行する</p></li><li><p>古いノードをシャットダウンする</p></li></ul><p><strong>3. ノード上のディスクサイズを減らす</strong></p><p>クラスターの全体的な RAM または CPU を変更せずに、ノード上のディスク サイズのみを削減したい場合は、各ノードのディスク サイズを削減できます。Elasticsearch ノード上のディスク サイズを縮小するのは簡単なプロセスではありません。</p><p>最も簡単な方法は通常次のようになります。</p><ul><li><p>ノードからシャードを移行する</p></li><li><p>ノードを停止する</p></li><li><p>適切なサイズの新しいデータボリュームをノードにマウントします</p></li><li><p>古いディスクボリュームから新しいボリュームにすべてのデータをコピーします</p></li><li><p>古いボリュームAを切り離す</p></li><li><p>ノードを起動し、シャードをノードに戻す</p></li></ul><p>これには、このプロセス中にノードからの追加シャードを一時的に保存するのに十分な容量が他のノードに必要です。多くの場合、このプロセスの管理にかかるコストは、ディスク使用量の潜在的な節約額を上回る可能性があります。このため、必要なディスク サイズを持つ新しいノードにノード全体を置き換える方が簡単な場合があります (上記の「既存のノードをより小さなノードに置き換える」を参照)。</p><p>不要なリソースに料金を支払う場合、リソースの使用率を最適化することでコストを削減できることは明らかです。</p><h2>ディスクサイズ、RAM、CPUの関係</h2><p>クラスター内のディスク容量と RAM の理想的な比率は、特定のユースケースによって異なります。このため、ストレージ容量の変更を検討する際には、現在のディスク/RAM/CPU の比率が適切にバランスされているかどうか、また、その結果として RAM/CPU を同じ比率で追加/削減する必要があるかどうかも考慮する必要があります。</p><p>RAM と CPU の要件は、<a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-indexing/">インデックス作成</a>アクティビティの量、クエリの数と種類、さらに検索および集約されるデータの量によって異なります。これは多くの場合、クラスターに保存されるデータの量に比例するため、ディスク サイズにも関連している必要があります。</p><p>ディスク容量と RAM の比率は、使用事例に応じて変わる可能性があります。ここでいくつかの例をご覧ください:</p><p></p><p>インデックスアクティビティ</p><p>保持</p><p>検索アクティビティ</p><p>ディスク容量</p><p>ラム</p><p>エンタープライズ検索アプリ</p><p>中程度のログ摂取</p><p>長さ</p><p>ライト</p><p>2TB</p><p>32GB</p><p>アプリ監視</p><p>集中的なログ取り込み</p><p>短い</p><p>ライト</p><p>1TB</p><p>32GB</p><p>電子商取引</p><p>軽量データインデックス</p><p>不定</p><p>重い</p><p>500GB</p><p>32GB</p><p><em>ノード マシンの構成の変更は、ノードのダウンタイムが発生する可能性があり、すでに過剰に負荷がかかっている他のノードにシャードが移行しないようにする必要があるため、慎重に行う必要があることに注意してください。</em></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/optimize-elasticsearch-disk-space-and-usage</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/optimize-elasticsearch-disk-space-and-usage</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt087c3d95b6cb59c5/6a17dbda445de986f54cffd9/5d41a078dd03e4480a0ff4e9591c8618b9bab4d0-720x420.png" length="0" type="image/png"/>
    <pubDate>Fri, 16 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[JavaScript で Elasticsearch を正しく使う方法、パート 1]]></title>
    <description><![CDATA[JavaScript で本番環境対応の Elasticsearch バックエンドを作成する方法を説明します。  

ElasticsearchをJavaScriptで使用して、クライアント/サーバーのベストプラクティスに従ってElasticsearchドキュメントにクエリを実行するために、さまざまな検索エンドポイントを持つサーバーを作成する方法をご覧ください。]]></description>
    <content:encoded><![CDATA[<p>これは、JavaScript で Elasticsearch を使用する方法を説明するシリーズの最初の記事です。このシリーズでは、JavaScript 環境で Elasticsearch を使用する方法の基本を学習し、検索アプリを作成するための最も関連性の高い機能とベスト プラクティスを確認します。最後には、JavaScript を使用して Elasticsearch を実行するために必要なすべてのことを理解できるようになります。</p><p>この最初の部分では、次の点を確認します。</p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#environment">環境</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#frontend,-backend,-or-serverless?">フロントエンド、バックエンド、それともサーバーレス？</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#connecting-the-client">クライアントの接続</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#indexing-documents">文書のインデックス作成</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#elasticsearch-client">Elasticsearchクライアント</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#semantic-mappings">セマンティックマッピング</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#bulk-helper">バルクヘルパー</a></p></li></ul></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#searching-data">データの検索</a></p><ul><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#lexical-query-(/search/lexic?q=%3Cquery-term%3E)">語彙クエリ</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#semantic-query-(/search/semantic?q=%3Cquery-term%3E)">セマンティッククエリ</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i#hybrid-query-(/search/hybrid?q=%3Cquery-term%3E)">ハイブリッドクエリ</a></p></li></ul></li></ul><p><a href="https://github.com/Delacrobix/JS-client-best-practices_article"><em><strong>ここで</strong></em></a><em> 例付きのソースコードを確認できます</em><em><strong> 。</strong></em></p><h3>Elasticsearch Node.js クライアントとは何ですか?</h3><p><a href="https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/index.html">Elasticsearch Node.js クライアント</a>は、Elasticsearch API からの HTTP REST 呼び出しを JavaScript に配置する JavaScript ライブラリです。これにより、処理が容易になり、ドキュメントのインデックス作成などのタスクを一括で簡素化するヘルパーが利用できるようになります。</p><h2>環境</h2><h3>フロントエンド、バックエンド、それともサーバーレス？</h3><p>JavaScript クライアントを使用して検索アプリを作成するには、Elasticsearch クラスターとクライアントを実行する JavaScript ランタイムという少なくとも 2 つのコンポーネントが必要です。</p><p>JavaScript クライアントはすべての Elasticsearch ソリューション (クラウド、オンプレミス、サーバーレス) をサポートしており、クライアントがすべてのバリエーションを内部で処理するため、ソリューション間に大きな違いはありません。そのため、どれを使用するかについて心配する必要はありません。</p><p>ただし、JavaScript ランタイムは<strong>ブラウザ</strong>から<strong>直接ではなく、サーバーから実行する必要があります。</strong></p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd3ec469c83e3a71a/6a17e3d5445de91da44d00b6/92ce6cfd923c8008fa44f617a58193642d9d5879-661x410.png" alt="JavaScript環境でのElasticsearch。" /><p>これは、ブラウザから Elasticsearch を呼び出すと、ユーザーがクラスター API キー、ホスト、クエリ自体などの機密情報を取得する可能性があるためです。Elasticsearch では<strong>、クラスターをインターネットに直接公開せず</strong>、このすべての情報を抽象化する中間層を使用して、ユーザーがパラメータのみを確認できるようにすることを推奨しています。このトピックの詳細については、<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/es-security-principles.html#security-protect-cluster-traffic">ここ を</a>ご覧ください。</p><p>次のようなスキーマを使用することをお勧めします。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4d7f215f2e70230a/6a17e3d6fbc5f83de6491a13/a08769f08ec73fe57bf2e961cfdfbb1cdd57919d-972x429.png" alt="Elasticsearch Node.jsクライアントをセットアップする。" /><p>この場合、クライアントは検索用語とサーバーの認証キーのみを送信し、サーバーはクエリと Elasticsearch との通信を完全に制御します。</p><h3>クライアントの接続</h3><p>まず、<a href="https://www.elastic.co/search-labs/tutorials/install-elasticsearch/elastic-cloud">次の手順</a>に従って API キーを作成します。</p><p>前の例に従って、シンプルな Express サーバーを作成し、Node.JS サーバーからのクライアントを使用してそのサーバーに接続します。</p><p>NPM を使用してプロジェクトを初期化し、Elasticsearch クライアントと<a href="https://expressjs.com/">Express をインストールします。</a>後者は、Node.js でサーバーを起動するためのライブラリです。Express を使用すると、HTTP 経由でバックエンドと対話できます。</p><p>プロジェクトを初期化しましょう:</p><p><code>npm init -y</code></p><p>依存関係をインストールします:</p><p><code>npm install @elastic/elasticsearch express split2 dotenv</code></p><p>詳しく説明しましょう:</p><ul><li><p><a href="https://www.npmjs.com/package/@elastic/elasticsearch"><em><strong>@elastic/elasticsearch</strong></em></a> : 公式Node.jsクライアントです</p></li><li><p><a href="https://www.npmjs.com/package/express"><em><strong>express</strong></em></a> : 軽量なNode.jsサーバーを立ち上げてElasticsearchを公開できるようになります</p></li><li><p><a href="https://www.npmjs.com/package/split2"><em><strong>split2</strong></em></a> : テキスト行をストリームに分割します。ndjsonファイルを1行ずつ処理するのに便利です</p></li><li><p><a href="https://www.npmjs.com/package/dotenv"><em><strong>dotenv</strong></em></a> : .env を使用して環境変数を管理できるようにしますファイル</p></li></ul><p>.envを作成するプロジェクトのルートにあるファイルを作成し、次の行を追加します。</p>ELASTICSEARCH_ENDPOINT="Your Elasticsearch endpoint"
ELASTICSEARCH_API_KEY="Your Elasticssearch API"<p>この方法では、 <code>dotenv</code>パッケージを使用してこれらの変数をインポートできます。</p><p><code>server.js</code>ファイルを作成します:</p>const express = require("express");
const bodyParser = require("body-parser");
const { Client } = require("@elastic/elasticsearch");
 
require("dotenv").config(); //environment variables setup

const ELASTICSEARCH_ENDPOINT = process.env.ELASTICSEARCH_ENDPOINT;
const ELASTICSEARCH_API_KEY = process.env.ELASTICSEARCH_API_KEY;
const PORT = 3000;


const app = express();

app.listen(PORT, () =&gt; {
  console.log("Server running on port", PORT);
});
app.use(bodyParser.json());


let esClient = new Client({
  node: ELASTICSEARCH_ENDPOINT,
  auth: { apiKey: ELASTICSEARCH_API_KEY },  
});

app.get("/ping", async (req, res) =&gt; {
  try {
    const result = await esClient.info();

    res.status(200).json({
      success: true,
      clusterInfo: result,
    });
  } catch (error) {
    console.error("Error getting Elasticsearch info:", error);

    res.status(500).json({
      success: false,
      clusterInfo: null,
      error: error.message,
    });
  }
});<p>このコードは、ポート 3000 をリッスンし、認証用の API キーを使用して Elasticsearch クラスターに接続する基本的な Express.js サーバーをセットアップします。これには、GET リクエストを介してアクセスすると、Elasticsearch クライアントの<code>.info()</code>メソッドを使用して Elasticsearch クラスターに基本情報を照会する /ping エンドポイントが含まれています。</p><p>クエリが成功した場合は、クラスター情報が JSON 形式で返され、それ以外の場合はエラー メッセージが返されます。サーバーは、JSON リクエスト本体を処理するために body-parser ミドルウェアも使用します。</p><p>ファイルを実行してサーバーを起動します。</p><p><code>node server.js</code></p><p>答えは次のようになるはずです:</p>Server running on port 3000<p>それでは、エンドポイント<code>/ping</code>を参照して、Elasticsearch クラスターのステータスを確認しましょう。</p>curl http://localhost:3000/ping
{
    "success": true,
    "clusterInfo": {
        "name": "instance-0000000000",
        "cluster_name": "61b7e19eec204d59855f5e019acd2689",
        "cluster_uuid": "BIfvfLM0RJWRK_bDCY5ldg",
        "version": {
            "number": "9.0.0",
            "build_flavor": "default",
            "build_type": "docker",
            "build_hash": "112859b85d50de2a7e63f73c8fc70b99eea24291",
            "build_date": "2025-04-08T15:13:46.049795831Z",
            "build_snapshot": false,
            "lucene_version": "10.1.0",
            "minimum_wire_compatibility_version": "8.18.0",
            "minimum_index_compatibility_version": "8.0.0"
        },
        "tagline": "You Know, for Search"
    }
}<h2>文書のインデックス作成</h2><p>接続すると、セマンティック検索用の<a href="https://www.elastic.co/search-labs/blog/semantic-search-simplified-semantic-text">semantic_text</a>やフルテキストクエリ用の text などのマッピングを使用してドキュメントのインデックスを作成できます。これら 2 つのフィールド タイプを使用すると、<a href="https://www.elastic.co/what-is/hybrid-search">ハイブリッド検索</a>も実行できます。</p><p>マッピングを生成し、ドキュメントをアップロードするために、新しい<code>load.js</code>ファイルを作成します。</p><h3>Elasticsearchクライアント</h3><p>まずクライアントをインスタンス化して認証する必要があります。</p>const { Client } = require("@elastic/elasticsearch");

const ELASTICSEARCH_ENDPOINT = "cluster/project_endpoint";
const ELASTICSEARCH_API_KEY = "apiKey";

const esClient = new Client({
  node: ELASTICSEARCH_ENDPOINT,
  auth: { apiKey: ELASTICSEARCH_API_KEY },
});<h3>セマンティックマッピング</h3><p>動物病院に関するデータを含むインデックスを作成します。飼い主様、ペット様、訪問の詳細に関する情報を保存します。</p><p>名前や説明など、全文検索を実行するデータはテキストとして保存されます。動物の種や品種などのカテゴリのデータは、キーワードとして保存されます。</p><p>さらに、すべてのフィールドの値を semantic_text フィールドにコピーして、その情報に対してもセマンティック検索を実行できるようにします。</p>const INDEX_NAME = "vet-visits";

const createMappings = async (indexName, mapping) =&gt; {
  try {
    const body = await esClient.indices.create({
      index: indexName,
      body: {
        mappings: mapping,
      },
    });

    console.log("Index created successfully:", body);
  } catch (error) {
    console.error("Error creating mapping:", error);
  }
};

await createMappings(INDEX_NAME, {
  properties: {
    owner_name: {
      type: "text",
      copy_to: "semantic_field",
    },
    pet_name: {
      type: "text",
      copy_to: "semantic_field",
    },
    species: {
      type: "keyword",
      copy_to: "semantic_field",
    },
    breed: {
      type: "keyword",
      copy_to: "semantic_field",
    },
    vaccination_history: {
      type: "keyword",
      copy_to: "semantic_field",
    },
    visit_details: {
      type: "text",
      copy_to: "semantic_field",
    },
    semantic_field: {
      type: "semantic_text",
    },
  },
});<h3>バルクヘルパー</h3><p>クライアントのもう 1 つの利点は、<a href="https://www.elastic.co/guide/en/elasticsearch/client/javascript-api/current/client-helpers.html#bulk-helper">一括ヘルパーを</a>使用してインデックスを一括で作成できることです。バルク ヘルパーを使用すると、同時実行、再試行、関数を通過して成功または失敗した各ドキュメントの処理などを簡単に処理できます。</p><p>このヘルパーの魅力的な機能は、ストリームを操作できることです。この機能を使用すると、ファイル全体をメモリに保存して Elasticsearch に一度に送信するのではなく、ファイルを 1 行ずつ送信できます。</p><p>Elasticsearch にデータをアップロードするには、プロジェクトのルートに data.ndjson というファイルを作成し、以下の情報を追加します (または、<a href="https://github.com/Delacrobix/JS-client-best-practices_article/blob/main/data.ndjson">ここ</a>からデータセットを含むファイルをダウンロードすることもできます)。</p>{"owner_name":"Alice Johnson","pet_name":"Buddy","species":"Dog","breed":"Golden Retriever","vaccination_history":["Rabies","Parvovirus","Distemper"],"visit_details":"Annual check-up and nail trimming. Healthy and active."}
{"owner_name":"Marco Rivera","pet_name":"Milo","species":"Cat","breed":"Siamese","vaccination_history":["Rabies","Feline Leukemia"],"visit_details":"Slight eye irritation, prescribed eye drops."}
{"owner_name":"Sandra Lee","pet_name":"Pickles","species":"Guinea Pig","breed":"Mixed","vaccination_history":[],"visit_details":"Loss of appetite, recommended dietary changes."}
{"owner_name":"Jake Thompson","pet_name":"Luna","species":"Dog","breed":"Labrador Mix","vaccination_history":["Rabies","Bordetella"],"visit_details":"Mild ear infection, cleaning and antibiotics given."}
{"owner_name":"Emily Chen","pet_name":"Ziggy","species":"Cat","breed":"Mixed","vaccination_history":["Rabies","Feline Calicivirus"],"visit_details":"Vaccination update and routine physical."}
{"owner_name":"Tomás Herrera","pet_name":"Rex","species":"Dog","breed":"German Shepherd","vaccination_history":["Rabies","Parvovirus","Leptospirosis"],"visit_details":"Follow-up for previous leg strain, improving well."}
{"owner_name":"Nina Park","pet_name":"Coco","species":"Ferret","breed":"Mixed","vaccination_history":["Rabies"],"visit_details":"Slight weight loss; advised new diet."}
{"owner_name":"Leo Martínez","pet_name":"Simba","species":"Cat","breed":"Maine Coon","vaccination_history":["Rabies","Feline Panleukopenia"],"visit_details":"Dental cleaning. Minor tartar buildup removed."}
{"owner_name":"Rachel Green","pet_name":"Rocky","species":"Dog","breed":"Bulldog Mix","vaccination_history":["Rabies","Parvovirus"],"visit_details":"Skin rash, antihistamines prescribed."}
{"owner_name":"Daniel Kim","pet_name":"Mochi","species":"Rabbit","breed":"Mixed","vaccination_history":[],"visit_details":"Nail trimming and general health check. No issues."}<p>バルク ヘルパーがファイル行を Elasticsearch に送信する間、split2 を使用してファイル行をストリーミングします。</p>const { createReadStream } = require("fs");
const split = require("split2");
 
const indexData = async (filePath, indexName) =&gt; {
  try {
    console.log(`Indexing data from ${filePath} into ${indexName}...`);

    const result = await esClient.helpers.bulk({
      datasource: createReadStream(filePath).pipe(split()),

      onDocument: () =&gt; {
        return {
          index: { _index: indexName },
        };
      },
      onDrop(doc) {
        console.error("Error processing document:", doc);
      },
    });

    console.log("Bulk indexing successful elements:", result.items.length);
  } catch (error) {
    console.error("Error indexing data:", error);
    throw error;
  }
};

await indexData("./data.ndjson", INDEX_NAME);<p>上記のコードは.ndjsonを読み取りますファイルを 1 行ずつ読み込み、 <code>helpers.bulk</code>メソッドを使用して各 JSON オブジェクトを指定された Elasticsearch インデックスに一括インデックスします。<code>createReadStream</code>と<code>split2</code>を使用してファイルをストリーミングし、各ドキュメントのインデックス メタデータを設定し、処理に失敗したドキュメントをログに記録します。完了すると、正常にインデックスが作成されたアイテムの数を記録します。</p><p><code>indexData</code>関数を使用する代わりに、Kibana を使用して UI 経由でファイルを直接アップロードし、<a href="https://www.elastic.co/docs/manage-data/ingest/upload-data-files">データ ファイルのアップロード UI を使用することもできます。</a></p><p>ファイルを実行して、ドキュメントを Elasticsearch クラスターにアップロードします。</p><p><code>node load.js</code></p>Creating mappings for index vet-visits...
Index created successfully: { acknowledged: true, shards_acknowledged: true, index: 'vet-visits' }
Indexing data from ./data.ndjson into vet-visits...
Bulk indexing completed. Total documents: 10, Failed: 0<h2>Elasticsearchでのデータ検索</h2><p><code>server.js</code>ファイルに戻って、語彙検索、セマンティック検索、ハイブリッド検索を実行するためのさまざまなエンドポイントを作成します。</p><p>簡単に言えば、これらのタイプの検索は相互に排他的ではありませんが、回答する必要がある質問の種類によって異なります。</p><p>クエリタイプ</p><p>使用事例</p><p>例題</p><p>語彙クエリ</p><p>質問内の単語または語根は、索引文書に表示される可能性があります。質問とドキュメント間のトークンの類似性。</p><p>青いスポーツTシャツを探しています。</p><p>セマンティッククエリ</p><p>質問内の単語は文書には表示されない可能性があります。質問とドキュメント間の概念的な類似性。</p><p>寒い季節用の服を探しています。</p><p>ハイブリッド検索</p><p>質問には語彙や意味の要素が含まれています。質問とドキュメント間のトークンと意味の類似性。</p><p>ビーチでの結婚式用にSサイズのドレスを探しています。</p><p>質問の<em><strong>語彙</strong></em>部分はタイトルや説明、またはカテゴリ名の一部である可能性が高く、<em><strong>意味</strong></em>部分はそれらの分野に関連する概念です。<em><strong>青は</strong></em>おそらくカテゴリ名または説明の一部であり、<em><strong>ビーチウェディングは</strong></em>そうではないかもしれませんが、意味的にはリネンの衣服に関連している可能性があります。</p><h3>語彙クエリ (/search/lexic?q=&lt;query_term&gt;)</h3><p>語彙検索 (フルテキスト検索とも呼ばれる) とは、トークンの類似性に基づいて検索することを意味します。つまり、分析後、検索内のトークンを含むドキュメントが返されます。</p><p>語彙検索の実践チュートリアルは、<a href="https://www.elastic.co/demo-gallery/lexical-search">こちらで</a>ご覧いただけます。</p>app.get("/search/lexic", async (req, res) =&gt; {
  const { q } = req.query;

  const INDEX_NAME = "vet-visits";

  try {
    const result = await esClient.search({
      index: INDEX_NAME,
      size: 5,
      body: {
        query: {
          multi_match: {
            query: q,
            fields: ["owner_name", "pet_name", "visit_details"],
          },
        },
      },
    });

    res.status(200).json({
      success: true,
      results: result.hits.hits
    });
  } catch (error) {
    console.error("Error performing search:", error);

    res.status(500).json({
      success: false,
      results: null,
      error: error.message,
    });
  }
});<p><em><strong>爪切り</strong></em>でテストする</p>curl http://localhost:3000/search/lexic?q=nail%20trimming<p>答え：</p>{
    "success": true,
    "results": [
        {
            "_index": "vet-visits",
            "_id": "-RY6RJYBLe2GoFQ6-9n9",
            "_score": 2.7075968,
            "_source": {
                "pet_name": "Mochi",
                "owner_name": "Daniel Kim",
                "species": "Rabbit",
                "visit_details": "Nail trimming and general health check. No issues.",
                "breed": "Mixed",
                "vaccination_history": []
            }
        },
        {
            "_index": "vet-visits",
            "_id": "8BY6RJYBLe2GoFQ6-9n9",
            "_score": 2.560356,
            "_source": {
                "pet_name": "Buddy",
                "owner_name": "Alice Johnson",
                "species": "Dog",
                "visit_details": "Annual check-up and nail trimming. Healthy and active.",
                "breed": "Golden Retriever",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Distemper"
                ]
            }
        }
    ]
}<h3>セマンティッククエリ (/search/semantic?q=&lt;query_term&gt;)</h3><p>セマンティック検索は、語彙検索とは異なり、ベクトル検索を通じて検索用語の意味に類似した結果を見つけます。</p><p>セマンティック検索の実践チュートリアルは、<a href="https://www.elastic.co/demo-gallery/semantic-search">こちらで</a>ご覧いただけます。</p>app.get("/search/semantic", async (req, res) =&gt; {
  const { q } = req.query;

  const INDEX_NAME = "vet-visits";

  try {
    const result = await esClient.search({
      index: INDEX_NAME,
      size: 5,
      body: {
        query: {
          semantic: {
            field: "semantic_field",
            query: q
          },
        },
      },
    });

    res.status(200).json({
      success: true,
      results: result.hits.hits,
    });
  } catch (error) {
    console.error("Error performing search:", error);

    res.status(500).json({
      success: false,
      results: null,
      error: error.message,
    });
  }
});<p>テスト対象:<em><strong>誰がペディキュアをしましたか?</strong></em></p>curl http://localhost:3000/search/semantic?q=Who%20got%20a%20pedicure?<p>答え：</p>{
    "success": true,
    "results": [
        {
            "_index": "vet-visits",
            "_id": "-RY6RJYBLe2GoFQ6-9n9",
            "_score": 4.861466,
            "_source": {
                "owner_name": "Daniel Kim",
                "pet_name": "Mochi",
                "species": "Rabbit",
                "breed": "Mixed",
                "vaccination_history": [],
                "visit_details": "Nail trimming and general health check. No issues."
            }
        },
        {
            "_index": "vet-visits",
            "_id": "8BY6RJYBLe2GoFQ6-9n9",
            "_score": 4.7152824,
            "_source": {
                "pet_name": "Buddy",
                "owner_name": "Alice Johnson",
                "species": "Dog",
                "visit_details": "Annual check-up and nail trimming. Healthy and active.",
                "breed": "Golden Retriever",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Distemper"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "9RY6RJYBLe2GoFQ6-9n9",
            "_score": 1.6717153,
            "_source": {
                "pet_name": "Rex",
                "owner_name": "Tomás Herrera",
                "species": "Dog",
                "visit_details": "Follow-up for previous leg strain, improving well.",
                "breed": "German Shepherd",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Leptospirosis"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "9xY6RJYBLe2GoFQ6-9n9",
            "_score": 1.5600781,
            "_source": {
                "pet_name": "Simba",
                "owner_name": "Leo Martínez",
                "species": "Cat",
                "visit_details": "Dental cleaning. Minor tartar buildup removed.",
                "breed": "Maine Coon",
                "vaccination_history": [
                    "Rabies",
                    "Feline Panleukopenia"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "-BY6RJYBLe2GoFQ6-9n9",
            "_score": 1.2696637,
            "_source": {
                "pet_name": "Rocky",
                "owner_name": "Rachel Green",
                "species": "Dog",
                "visit_details": "Skin rash, antihistamines prescribed.",
                "breed": "Bulldog Mix",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus"
                ]
            }
        }
    ]
}<h3>ハイブリッド クエリ (/search/hybrid?q=&lt;query_term&gt;)</h3><p>ハイブリッド検索により、セマンティック検索と語彙検索を組み合わせることができるため、両方の長所を活用できます。つまり、トークンによる検索の精度と、セマンティック検索の意味の近似性の両方が得られます。</p>app.get("/search/hybrid", async (req, res) =&gt; {
  const { q } = req.query;

  const INDEX_NAME = "vet-visits";

  try {
    const result = await esClient.search({
      index: INDEX_NAME,
      body: {
        retriever: {
          rrf: {
            retrievers: [
              {
                standard: {
                  query: {
                    bool: {
                      must: {
                         multi_match: {
             query: q,
            fields: ["owner_name", "pet_name", "visit_details"],
          },
                      },
                    },
                  },
                },
              },
              {
                standard: {
                  query: {
                    bool: {
                      must: {
                        semantic: {
                          field: "semantic_field",
                          query: q,
                        },
                      },
                    },
                  },
                },
              },
            ],
          },
        },
        size: 5,
      },
    });

    res.status(200).json({
      success: true,
      results: result.hits.hits,
    });
  } catch (error) {
    console.error("Error performing search:", error);

    res.status(500).json({
      success: false,
      results: null,
      error: error.message,
    });
  }
});<p>「<em><strong>ペディキュアや歯科治療を受けた人はいますか？」</strong></em>という質問をしてテストします。</p>curl http://localhost:3000/search/hybrid?q=who%20got%20a%20pedicure%20or%20dental%20treatment<p>対応：</p>{
    "success": true,
    "results": [
        {
            "_index": "vet-visits",
            "_id": "9xY6RJYBLe2GoFQ6-9n9",
            "_score": 0.032522473,
            "_source": {
                "pet_name": "Simba",
                "owner_name": "Leo Martínez",
                "species": "Cat",
                "visit_details": "Dental cleaning. Minor tartar buildup removed.",
                "breed": "Maine Coon",
                "vaccination_history": [
                    "Rabies",
                    "Feline Panleukopenia"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "-RY6RJYBLe2GoFQ6-9n9",
            "_score": 0.016393442,
            "_source": {
                "pet_name": "Mochi",
                "owner_name": "Daniel Kim",
                "species": "Rabbit",
                "visit_details": "Nail trimming and general health check. No issues.",
                "breed": "Mixed",
                "vaccination_history": []
            }
        },
        {
            "_index": "vet-visits",
            "_id": "8BY6RJYBLe2GoFQ6-9n9",
            "_score": 0.015873017,
            "_source": {
                "pet_name": "Buddy",
                "owner_name": "Alice Johnson",
                "species": "Dog",
                "visit_details": "Annual check-up and nail trimming. Healthy and active.",
                "breed": "Golden Retriever",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Distemper"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "9RY6RJYBLe2GoFQ6-9n9",
            "_score": 0.015625,
            "_source": {
                "pet_name": "Rex",
                "owner_name": "Tomás Herrera",
                "species": "Dog",
                "visit_details": "Follow-up for previous leg strain, improving well.",
                "breed": "German Shepherd",
                "vaccination_history": [
                    "Rabies",
                    "Parvovirus",
                    "Leptospirosis"
                ]
            }
        },
        {
            "_index": "vet-visits",
            "_id": "8xY6RJYBLe2GoFQ6-9n9",
            "_score": 0.015384615,
            "_source": {
                "pet_name": "Luna",
                "owner_name": "Jake Thompson",
                "species": "Dog",
                "visit_details": "Mild ear infection, cleaning and antibiotics given.",
                "breed": "Labrador Mix",
                "vaccination_history": [
                    "Rabies",
                    "Bordetella"
                ]
            }
        }
    ]
}<h2>まとめ</h2><p>このシリーズの最初の部分では、クライアント/サーバーのベストプラクティスに従って、環境を設定し、さまざまな検索エンドポイントを持つサーバーを作成し、Elasticsearch ドキュメントをクエリする方法を説明しました。シリーズの<a href="https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i">パート 2</a>では、本番環境のベスト プラクティスと、サーバーレス環境で Elasticsearch Node.js クライアントを実行する方法について学習します。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/how-to-use-elasticsearch-in-javascript-part-i</guid>
    <category><![CDATA[JavaScript]]></category>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Jeffrey Rengifo]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt16d00c8a548b32e8/6a17e3d8fbc5f8c740491a19/72200540ed258779d87e53a72ea189f8a138540c-1600x901.png" length="0" type="image/png"/>
    <pubDate>Thu, 15 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearchインデックスのレプリカ数の設定方法]]></title>
    <description><![CDATA[Elasticsearchインデックスでnumber_of_replicasを構成して、検索パフォーマンスを向上させ、ノード障害に対する耐性を高める方法を学びます。 
]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch は、大量のデータを処理し、高い可用性を提供できる分散システムとして設計されています。これを可能にする重要な機能の 1 つは、 <code>number_of_replicas</code>設定によって制御されるインデックス レプリケーションの概念です。この記事では、この設定の詳細、その影響、および適切な構成方法について詳しく説明します。</p><h2>Elasticsearchにおけるレプリカの役割</h2><p>Elasticsearch では、インデックスは複数のプライマリ シャードに分割されたドキュメントのコレクションです。各プライマリ シャードは自己完結型の Apache Lucene インデックスであり、インデックス内のドキュメントはすべてのプライマリ シャードに分散されます。高可用性とデータの冗長性を確保するために、Elasticsearch では各シャードにレプリカと呼ばれる 1 つ以上のコピーを持たせることができます。<code>number_of_replicas</code>設定は、Elasticsearch がインデックス内の各プライマリ シャードに対して作成するレプリカ シャード (コピー) の数を制御します。デフォルトでは、Elasticsearch はプライマリ シャードごとに 1 つのレプリカを作成しますが、これはシステムの要件に応じて変更できます。</p><h2>number_of_replicas の設定</h2><p><code>number_of_replicas</code>設定は、インデックスの作成時に構成することも、後で更新することもできます。インデックス作成時に設定する方法は次のとおりです。</p>PUT /my_index
{
  "settings": {
    "number_of_replicas": 2
  }
}<p>この例では、Elasticsearch は<code>my_index</code>インデックス内のプライマリ シャードごとに 2 つのレプリカを作成します。</p><p>既存のインデックスの<code>number_of_replicas</code>設定を更新するには、 <code>_settings</code> API を使用できます。</p>PUT /my_index/_settings
{
  "number_of_replicas": 3
}<p>このコマンドは、 <code>my_index</code>インデックスを更新して、プライマリ シャードごとに 3 つのレプリカを作成します。</p><h2>number_of_replicas設定の影響</h2><p><code>number_of_replicas</code>設定は、Elasticsearch<a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-cluster/">クラスター</a>のパフォーマンスと復元力に大きな影響を与えます。考慮すべき重要なポイントは次のとおりです。</p><ol><li><p><strong>データの冗長性と可用性:</strong> <code>number_of_replicas</code>を増やすと、各シャードのコピーがさらに作成され、データの可用性が向上します。ノードに障害が発生した場合でも、Elasticsearch は残りの<a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-node/">ノード</a>上のレプリカ シャードからデータを提供できます。</p></li><li><p><strong>検索パフォーマンス:</strong>レプリカ シャードは読み取り要求を処理できるため、レプリカの数を増やすと、負荷がより多くのシャードに分散され、検索パフォーマンスが向上します。</p></li><li><p><strong>書き込みパフォーマンス:</strong>ただし、各書き込み操作はシャードのすべてのコピーに対して実行する必要があります。したがって、 <code>number_of_replicas</code>大きくすると、書き込みごとに実行する必要がある操作の数が増えるため、<a href="https://opster.com/guides/elasticsearch/glossary/elasticsearch-indexing/">インデックス作成の</a>パフォーマンスが低下する可能性があります。</p></li><li><p><strong>ストレージ要件:</strong>レプリカが増えると、ストレージ容量も増えます。追加のレプリカを保存するのに十分な容量がクラスターにあることを確認する必要があります。</p></li><li><p><strong>ノード障害に対する耐性:</strong>クラスター内のノードの数を考慮して<code>number_of_replicas</code>を設定する必要があります。<code>number_of_replicas</code>がノード数以上である場合、クラスターはデータ損失なしで複数のノードの障害を許容できます。</p></li></ol><h2>number_of_replicas の設定に関するベストプラクティス</h2><p>最適な<code>number_of_replicas</code>設定は、システムの特定の要件によって異なります。ただし、一般的なベストプラクティスをいくつか示します。</p><ul><li><p>単一ノード クラスターの場合、レプリカを保持する他のノードがないため、 <code>number_of_replicas</code> 0 に設定する必要があります。</p></li><li><p>マルチノード クラスターの場合、データの冗長性と高可用性を確保するために、 <code>number_of_replicas</code>少なくとも 1 に設定する必要があります。</p></li><li><p>検索パフォーマンスを優先する場合は、 <code>number_of_replicas</code>を増やすことを検討してください。ただし、書き込みパフォーマンスとストレージ要件とのトレードオフに留意してください。</p></li><li><p>クラスターに追加のレプリカを保存するのに十分な容量があることを常に確認してください。</p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-index-number-of_replicas</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-index-number-of_replicas</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltd041e871a8935448/6a17de320b0bedf404dd34ab/23b96aaa1a38b1f4747b4a87695d816f24c0cf70-720x421.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 14 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch のドキュメントからフィールドを削除する]]></title>
    <description><![CDATA[Update API、スクリプト、または単一削除や一括削除のための再インデックスを使用して、Elasticsearchドキュメントからフィールドを削除する方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch では、ドキュメントからフィールドを削除することが一般的な要件です。これは、インデックスから不要な情報や古い情報を削除する場合に役立ちます。この記事では、Elasticsearch 内のドキュメントからフィールドを削除するさまざまな方法を、例と手順とともに説明します。 </p><h2>方法1: Update APIを使用する</h2><p><a href="https://www.elastic.co/docs/reference/elasticsearch/rest-apis/update-document">Update API</a>を使用すると、ドキュメントのソースを変更するスクリプトを提供することでドキュメントを更新できます。このAPIを使用して、フィールドをnullに設定して、ドキュメントからフィールドを削除できます。以下はその手順のステップ別のガイドです。</p><p>1. 更新するドキュメントのインデックス、ドキュメント タイプ (Elasticsearch 6.x 以前を使用している場合)、およびドキュメント ID を特定します。</p><p>2. フィールドを null に設定するスクリプト、またはソース ドキュメントからフィールドを削除するスクリプトで Update API を使用します。次の例は、「my_index」インデックス内の ID「1」のドキュメントから「field_to_delete」フィールドを削除する方法を示しています。</p>POST /my_index/_update/1
{
  "script": "ctx._source.remove('field_to_delete')"
}<p>3. リクエストを実行します。成功した場合、Elasticsearch はドキュメントが更新されたことを示す応答を返します。</p><p>注: このメソッドは、指定されたドキュメントからフィールドのみを削除します。フィールドはマッピングおよびインデックス内の他のドキュメントに引き続き存在します。</p><h2>方法2：変更されたソースでの再インデックス</h2><p>インデックス内のすべてのドキュメントからフィールドを削除したい場合、<a href="https://www.elastic.co/docs/api/doc/elasticsearch/operation/operation-reindex">Reindex API</a>を使用して、変更されたソースで新しいインデックスを作成できます。方法は以下の通りです。</p><p>1. 元のインデックスと同じ設定とマッピングを持つ新しいインデックスを作成します。Get Index API を使用して、元のインデックスの設定とマッピングを取得できます。</p><p>2. Reindex API を使用して、ソースからフィールドを削除しながら、元のインデックスから新しいインデックスにドキュメントをコピーします。次の例は、「my_index」インデックス内のすべてのドキュメントから「field_to_delete」フィールドを削除する方法を示しています。</p>POST /_reindex
{
  "source": {
    "index": "my_index"
  },
  "dest": {
    "index": "new_index"
  },
  "script": {
    "source": "ctx._source.remove('field_to_delete')"
  }
}<p>
3. 新しいインデックスに、フィールドが削除された正しいドキュメントが含まれていることを確認します。</p><p>4. すべてが問題なければ、元のインデックスを削除し、必要に応じて、元のインデックス名を持つエイリアスを新しいインデックスに追加できます。</p><h2>方法3：マッピングの更新と再インデックス</h2><p>マッピングからフィールドとインデックス内のすべてのドキュメントを削除する場合は、マッピングを更新してからドキュメントのインデックスを再作成できます。やり方は次のとおりです:</p><p>1. 元のインデックスと同じ設定で新しいインデックスを作成します。</p><p>2. Get Mapping API を使用して、元のインデックスのマッピングを取得します。</p><p>3. 削除するフィールドを削除してマッピングを変更します。</p><p>4. Put Mapping API を使用して、変更したマッピングを新しいインデックスに適用します。</p><p>5. 方法 2 の説明に従って、Reindex API を使用して、元のインデックスから新しいインデックスにドキュメントをコピーします。</p><p>6. 新しいインデックスに、フィールドが削除された正しいドキュメントが含まれていること、およびマッピングにフィールドが存在しないことを確認します。</p><p>7. 問題がなければ元のインデックスを削除し、必要に応じて元のインデックス名でエイリアスを追加できます。</p><h2>まとめ</h2><p>この記事では、Elasticsearch のドキュメントからフィールドを削除する 3 つの方法 (Update API の使用、変更されたソースによる再インデックス、マッピングの更新と再インデックス) について説明しました。それぞれの方法には独自の使用例とトレードオフがあるため、要件に最も適したものを選択してください。変更を本番環境に適用する前に、必ず変更をテストし、結果を確認してください。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-delete-field-from-document</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-delete-field-from-document</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt8deb617c89943b69/6a17e26c4b055d209e43212f/89278eb7309b7f3018c61be2b514d1fd25b9564d-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Fri, 09 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearchで2つのインデックスを結合する方法]]></title>
    <description><![CDATA[Elasticsearch で 2 つのインデックスを結合するための用語クエリ、Logstash elasticsearch フィルター、エンリッチ プロセッサ、ES|QL の使用方法を説明します。]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch では、2 つのインデックスを結合することは、従来の SQL リレーショナル データベースほど簡単ではありません。ただし、Elasticsearch が提供する特定のテクニックと機能を使用すれば、同様の結果を得ることは可能です。</p><p>歴史的に、多くの人々は、異なるインデックスを結合するメカニズムとして<a href="https://www.elastic.co/jp/docs/reference/elasticsearch/mapping-reference/nested"><code>nested</code></a><a href="https://www.elastic.co/jp/docs/reference/elasticsearch/mapping-reference/nested">フィールド タイプ</a>を使用してきました。しかし、クエリのコストが高く、Kibana、特にLensの視覚化のサポートが不完全であるため、制限がありました。</p><p>この記事では、Elasticsearch で 2 つのインデックスを結合するプロセスを詳しく説明し、次のアプローチに焦点を当てます。 </p><ol><li><p><code>terms</code>クエリの使用</p></li><li><p>取り込みパイプラインで<code>enrich</code>プロセッサを使用する</p></li><li><p>Logstash <code>elasticsearch</code>フィルター プラグイン</p></li><li><p>ES|QL <code>ENRICH</code></p></li><li><p>ES|QL <code>LOOKUP JOIN</code></p></li></ol><h2>用語クエリの使用</h2><p><a href="https://www.elastic.co/jp/docs/reference/query-languages/query-dsl/query-dsl-terms-query">用語クエリは</a>、Elasticsearch で 2 つのインデックスを結合する最も効果的な方法の 1 つです。このクエリは、特定のフィールドに 1 つ以上の正確な用語を含むドキュメントを取得するために使用されます。ここでは、これを使用して 2 つのインデックスを結合する方法について説明します。</p><p>まず、最初のインデックスから必要なデータを取得する必要があります。これは、単純な GET リクエストを使用して<code>_source</code>属性から値を取得することで実行できます。</p># Simple GET request
GET first_index/_search<p>最初のインデックスからデータを取得したら、それを使用して 2 番目のインデックスをクエリできます。これは、一致させるフィールドと値を指定する<code>terms</code>クエリを使用して行われます。</p><p>次に例を示します。</p>GET second_index/_search
{
  "query": {
    "terms": {
      "field_in_second_index": ["value1_from_first_index", "value2_from_first_index"]
    }
  }
}<p>
この例では、 <code>field_in_second_index</code> 、最初のインデックスの値と一致させる 2 番目のインデックスのフィールドです。<code>value1_from_first_index</code>と<code>value2_from_first_index</code> 、2 番目のインデックスで一致させる最初のインデックスの値です。</p><p>用語クエリは<a href="https://www.elastic.co/jp/docs/reference/query-languages/query-dsl/query-dsl-terms-query#query-dsl-terms-lookup">、用語ルックアップ</a>と呼ばれる手法を使用して、上記の 2 つの手順を 1 回のショットで実行するためのサポートも提供します。Elasticsearch は、別のインデックスから一致する値を透過的に取得します。たとえば、プレーヤーのリストを含むチーム インデックスがある場合:</p>PUT teams/_doc/team1
{
  "players":   ["john", "bill", "michael"]
}
PUT teams/_doc/team2
{
  "players":   ["aaron", "joe", "donald"]
}<p>以下に示すように、team1 でプレイしているすべての人々の人インデックスをクエリすることができます。</p>GET people/_search?pretty
{
  "query": {
    "terms": {
        "name" : {
            "index" : "teams",
            "id" : "team1",
            "path" : "players"
        }
    }
  }
}<p>上記の例では、Elasticsearchはチームインデックス内のID team1 を持つドキュメントからプレーヤー名を透過的に取得します（つまり、たとえば、「john」、「bill」、「michael」など) を検索し、名前フィールドにこれらの値のいずれかを含む人物インデックス内のすべてのドキュメントを検索します。</p><p>興味がある方のために、同等の SQL クエリは次のようになります。</p><h2>エンリッチプロセッサの使用</h2><p><a href="https://www.elastic.co/jp/docs/reference/enrich-processor/enrich-processor"><code>enrich</code></a><a href="https://www.elastic.co/jp/docs/reference/enrich-processor/enrich-processor">プロセッサは</a>、Elasticsearch 内の 2 つのインデックスを結合するために使用できるもう 1 つの強力なツールです。このプロセッサは、事前に定義されたエンリッチ インデックスからデータを追加することで、受信ドキュメントのデータをエンリッチします。</p><p>エンリッチ プロセッサを使用して 2 つのインデックスを結合する方法は次のとおりです。</p><p>1. まず、エンリッチポリシーを作成する必要があります。このポリシーは、エンリッチメントに使用するインデックス、一致させるフィールド、および受信ドキュメントのエンリッチメントに使用するフィールドを定義します。</p><p>次に例を示します。</p>PUT _enrich/policy/my_enrich_policy
{
  "match": {
    "indices": "first_index",
    "match_field": "field_in_first_index",
    "enrich_fields": ["field_to_enrich"]
  }
}<p>2. ポリシーが作成されたら、それを実行して、新しく作成されたポリシーからエンリッチ インデックスを作成する必要があります。</p>PUT _enrich/policy/my_enrich_policy/_execute<p>これにより、エンリッチメント中に使用される新しい非表示のエンリッチメント インデックスが構築されます。ソース インデックスのサイズによっては、この操作に時間がかかる場合があります。次のステップに進む前に、エンリッチポリシーが完全に構築されていることを確認してください。</p><p>3. エンリッチポリシーを構築したら、取り込みパイプラインでエンリッチプロセッサを使用して、受信ドキュメントのデータをエンリッチできます。</p>PUT _ingest/pipeline/my_pipeline
{
  "processors": [
    {
      "enrich": {
        "policy_name": "my_enrich_policy",
        "field": "field_in_second_index",
        "target_field": "enriched_field"
      }
    }
  ]
}<p>この例では、 <code>field_in_second_index</code> 、最初のインデックスの<code>match_field</code>と一致する必要がある 2 番目のインデックスのフィールドです。<code>enriched_field</code> 、最初のインデックスの<code>enrich_fields</code>から拡張されたデータを格納する、2 番目のインデックスの新しいフィールドです。</p><p>このアプローチの欠点の 1 つは、 <code>first_index</code>のデータが変更された場合、エンリッチ ポリシーを再実行する必要があることです。エンリッチされたインデックスは、その構築元となったソース インデックスから自動的に更新または同期されることはありません。ただし、 <code>first_index</code>が比較的安定している場合は、このアプローチはうまく機能します。</p><h2>Logstash elasticsearch フィルター プラグイン</h2><p>Logstash を使用する場合、上記の<code>enrich</code>プロセッサに似た別のオプションとして、 <code>elasticsearch</code>フィルター プラグインを使用して、指定されたクエリに基づいてイベントに関連フィールドを追加する方法があります。Logstash パイプラインの構成は、 <code>my-pipeline.conf</code>などの<code>.conf</code>ファイルに保存されます。</p><p>パイプラインが<a href="https://www.elastic.co/jp/docs/reference/logstash/plugins/plugins-inputs-elasticsearch"><code>elasticsearch</code></a><a href="https://www.elastic.co/jp/docs/reference/logstash/plugins/plugins-inputs-elasticsearch">入力プラグイン</a>を使用して Elasticsearch からログを取得し、選択範囲を絞り込むクエリを実行しているとします。</p>input {
  # Read all documents from Elasticsearch matching the given query
  elasticsearch {
    hosts =&gt; "localhost"
    query =&gt; '{ "query": { "match": { "statuscode": 200 } }, "sort": [ "_doc" ] }'
  }
}<p>特定のインデックスからの情報を使用してこれらのメッセージを拡充したい場合は、 <code>filter</code>セクションの<a href="https://www.elastic.co/jp/docs/reference/logstash/plugins/plugins-filters-elasticsearch"><code>elasticsearch</code></a><a href="https://www.elastic.co/jp/docs/reference/logstash/plugins/plugins-filters-elasticsearch">フィルター プラグイン</a>を使用してログを拡充できます。</p>filter {
   elasticsearch {
      hosts =&gt; ["localhost"]
      index =&gt; "index_name"
      query =&gt; "type:start AND operation:%{[opid]}"
      fields =&gt; { "@timestamp" =&gt; "started" }
   }
}<p>上記のコードは、インデックス<code>index_name</code>から、 <code>type</code>が開始され、操作フィールドが指定された<code>opid</code>と一致するドキュメントを検索し、 <code>@timestamp</code>フィールドの値を<code>started</code>という名前の新しいフィールドにコピーします。</p><p>強化されたドキュメントは適切な出力ソース（この場合は<a href="https://www.elastic.co/jp/docs/reference/logstash/plugins/plugins-outputs-elasticsearch"><code>elasticsearch</code></a><a href="https://www.elastic.co/jp/docs/reference/logstash/plugins/plugins-outputs-elasticsearch">出力プラグイン</a>を使用して Elasticsearch ）に送信されます。</p>output {
    elasticsearch {
        hosts =&gt; "localhost"
        data_stream =&gt; "true"
    }
}<p>すでに Logstash を使用している場合、このオプションは、エンリッチメント ロジックを 1 か所に統合し、新しいイベントが発生したときに処理するのに役立ちます。ただし、そうでない場合は、ソリューションが複雑になり、実行および保守する必要がある別のコンポーネントが追加されることになります。</p><h2>ES|QL エンリッチ</h2><p>バージョン 8.14 で GA となった<a href="https://www.elastic.co/jp/docs/explore-analyze/query-filter/languages/esql">ES|QL</a>は、Elasticsearch でサポートされるパイプ クエリ言語であり、データのフィルタリング、変換、分析を可能にします。ENRICH 処理コマンドを使用すると、エンリッチ ポリシーを使用して既存のインデックスからデータを追加できます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbeb8992bde773461/6a17f6b663baff00c9741dd4/03aadddc08afffff3f6526c9c052999c97fa09dd-1600x989.png" alt="esql エンリッチ" /><p>元のエンリッチ プロセッサの例と同じポリシー<code>my_enrich_policy</code>を使用すると、ES|QL の例は次のようになります。</p><p>一致フィールドとエンリッチメント フィールド (この例ではそれぞれ<code>field_in_first_index</code>と<code>field_to_enrich</code>をオーバーライドすることもできます。</p><p>明らかな制限は、最初にエンリッチポリシーを指定する必要があることですが、ES|QL では、必要に応じてフィールドを微調整できる柔軟性が提供されます。</p><h2>ES|QL ルックアップ結合</h2><p>Elasticsearch 8.18 では、Elasticsearch でインデックスを結合する新しい方法、つまり<code>LOOKUP JOIN</code>コマンドが導入されました。このコマンドは、結合の右側にある新しい<a href="https://www.elastic.co/jp/docs/reference/elasticsearch/index-settings/index-modules#index-mode-setting">ルックアップ インデックス モード</a>を使用して、SQL スタイルの LEFT OUTER JOIN として動作します。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt783ffb3f9802f92d/6a17f6b8e9ea870608a9c788/1d73495979c4d6bb675c4c966ea86d9a72dc1c48-510x605.png" alt="ES|QL ルックアップ結合" /><p>前の例をもう一度見てみると、新しいクエリは次のようになります。ここで、 <code>match_field</code> <code>first_index</code>と<code>second_index</code>両方に存在する必要があります。</p><p>LOOKUP JOIN が他のアプローチよりも優れている点は、 <code>enrich</code>ポリシーが不要であり、したがってポリシーの設定に関連する追加の処理も必要ないことです。これは、この記事で説明した他のアプローチとは異なり、頻繁に変更されるエンリッチメント データを扱う場合に役立ちます。</p><h2>まとめ</h2><p>結論として、Elasticsearch は従来の結合操作をサポートしていませんが、同様の結果を実現するために使用できるさまざまな機能を提供しています。具体的には、以下を使用して結合操作を実現する方法について説明しました。</p><ol><li><p><code>terms</code>クエリ</p></li><li><p>取り込みパイプラインの<code>enrich</code>プロセッサ</p></li><li><p>Logstash <code>elasticsearch</code>フィルター プラグイン</p></li><li><p>ES|QL <code>ENRICH</code></p></li><li><p>ES|QL <code>LOOKUP JOIN</code></p></li></ol><p>これらの方法には限界があり、特定の要件とデータの性質に基づいて慎重に使用する必要があることに注意することが重要です。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-join-two-indexes</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-join-two-indexes</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Carly Richmond]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt74822b3b7cb2a41a/6a17f6b97f6f156288c09cc7/0d4736d10fa3e12e6233cd59993299c7bd48911b-680x450.png" length="0" type="image/png"/>
    <pubDate>Wed, 07 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch のスコアリングと Explain API を理解する]]></title>
    <description><![CDATA[Elasticsearch のスコアリングメカニズムと、Explain API を使用して検索する関連性を監査し、ドキュメントのランキングを向上させるための実用的なスコアリング機能について学びます。]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch は、インデックス内の各ドキュメントのスコアを計算して、高速かつ関連性の高い検索結果を提供する強力な検索エンジンです。このスコアは検索結果の順序を決定する上で重要な要素となります。この記事では、Elasticsearch のスコアリング メカニズムを詳しく説明し、スコアリング プロセスを理解するのに役立つ Explain API について説明します。</p><h2>Elasticsearchのスコアリングメカニズム</h2><p>Elasticsearch は、デフォルトで Practical Scoring Function (BM25) と呼ばれるスコアリング モデルを使用します。このモデルは確率的情報検索理論に基づいており、用語頻度、逆文書頻度、フィールド長の正規化などの要素を考慮に入れています。これらの要因について簡単に説明しましょう。</p><ol><li><p><strong>用語頻度 (TF):</strong>これは、ドキュメント内で用語が出現する回数を表します。用語の頻度が高いほど、用語とドキュメントの関係が強くなることを示します。</p></li><li><p><strong>逆文書頻度 (IDF):</strong>この要素は、文書コレクション全体における用語の重要度を測定します。多くのドキュメントに出現する用語は重要度が低いとみなされ、より少ないドキュメントに出現する用語は重要度が高いとみなされます。</p></li><li><p><strong>フィールド長の正規化</strong>: この要素は、用語が表示されるフィールドの長さを考慮します。短いフィールドでは用語がより重要であるとみなされるため、短いフィールドにはより大きな重みが与えられます。</p></li></ol><h2>Explain APIの使用</h2><p>Elasticsearch の Explain API は、スコアリング プロセスを理解するための貴重なツールです。特定のドキュメントのスコアがどのように計算されたかについての詳細な説明を提供します。Explain API を使用するには、次のエンドポイントに GET リクエストを送信する必要があります。</p>GET /&lt;index&gt;/_explain/&lt;document_id&gt;<p>リクエスト本文には、スコアリングを理解したいクエリを指定する必要があります。次に例を示します。</p>{
  "query": {
    "match": {
      "title": "elasticsearch"
    }
  }
}<p>Explain API からの応答には、個々の要素 (TF、IDF、フィールド長の正規化) とそれらが最終スコアに与える影響など、スコアリング プロセスの詳細な内訳が含まれます。応答の例は次のとおりです。</p>{
  "_index": "example_index",
  "_type": "_doc",
  "_id": "1",
  "matched": true,
  "explanation": {
    "value": 1.2,
    "description": "weight(title:elasticsearch in 0) [PerFieldSimilarity], result of:",
    "details": [
      {
        "value": 1.2,
        "description": "score(doc=0,freq=1.0 = termFreq=1.0\n), product of:",
        "details": [
          {
            "value": 2.2,
            "description": "idf, computed as log(1 + (docCount - docFreq + 0.5) / (docFreq + 0.5)) from:",
            "details": [
              {
                "value": 1,
                "description": "docFreq",
                "details": []
              },
              {
                "value": 1,
                "description": "docCount",
                "details": []
              }
            ]
          },
          {
            "value": 0.5,
            "description": "tfNorm, computed as (freq * (k1 + 1)) / (freq + k1 * (1 - b + b * fieldLength / avgFieldLength)) from:",
            "details": [
              {
                "value": 1,
                "description": "termFreq=1.0",
                "details": []
              },
              {
                "value": 1.2,
                "description": "parameter k1",
                "details": []
              },
              {
                "value": 0.75,
                "description": "parameter b",
                "details": []
              },
              {
                "value": 1,
                "description": "avgFieldLength",
                "details": []
              },
              {
                "value": 1,
                "description": "fieldLength",
                "details": []
              }
            ]
          }
        ]
      }
    ]
  }
}<p>この例では、応答は、スコア 1.2 が IDF 値 (2.2) と tfNorm 値 (0.5) の積であることを示しています。詳細な説明は、スコアに影響を与える要因を理解するのに役立ち、検索の関連性を微調整するのに役立ちます。</p><h2>まとめ</h2><p>Elasticsearch スコアリングは、関連性の高い検索結果を提供する上で重要な要素です。スコアリング メカニズムを理解し、Explain API を使用することで、検索結果に影響を与える要因についての洞察を得て、検索クエリを最適化し、関連性とパフォーマンスを向上させることができます。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-scoring-and-explain-api</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-scoring-and-explain-api</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe7de1872f1527e3/6a17de303e9e452974ba1374/a70c5403064d5bbceff66a17373332362227f13c-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 05 May 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[2つのフィールドによるElasticsearch検索]]></title>
    <description><![CDATA[複数一致クエリ、boolクエリ、クエリタイムフィールドブースティングなど、2つのフィールドで検索する技術を探ります。]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch で複数のフィールドを検索することは、多くのアプリケーションで一般的な要件です。この記事では、複数一致クエリ、ブールクエリ、クエリ時のフィールドブースティングなど、2 つのフィールドで検索を実行するための高度な手法について説明します。これらのテクニックは、ユーザーにとってより正確で関連性の高い検索結果を作成するのに役立ちます。</p><h2>2つのフィールドで検索を実行する高度なテクニック</h2><h3>1. 複数一致クエリ</h3><p>複数一致クエリを使用すると、複数のフィールドにわたって単一のクエリ文字列を検索できます。これは、2 つのフィールドのいずれかに指定されたクエリ文字列を含むドキュメントを検索する場合に便利です。以下は、「title」または「description」フィールドで「example」という用語を検索する複数一致クエリの例です。</p>{
  "query": {
    "multi_match": {
      "query": "example",
      "fields": ["title", "description"]
    }
  }
}<h3>2. ブールクエリ</h3><p>bool クエリを使用すると、ブールロジックを使用して複数のクエリを組み合わせることができます。「should」句を使用すると、2 つのフィールドのいずれかでクエリに一致するドキュメントを検索できます。以下は、フィールド「title」と「description」で「example」という用語を検索するブールクエリの例です。</p>{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": "example"}},
        {"match": {"description": "example"}}
      ]
    }
  }
}<h3>3. クエリ時のフィールドブースティング</h3><p>場合によっては、検索中にあるフィールドを他のフィールドよりも重視したいことがあります。これを実現するには、クエリ時にフィールドにブースト係数を適用します。ブースト値が高いほど、フィールドの重みが増し、最終的な検索スコアに影響を与える可能性が高くなります。以下は、「タイトル」フィールドにブースト係数を適用した複数一致クエリの例です。</p>{
  "query": {
    "multi_match": {
      "query": "example",
      "fields": ["title^3", "description"]
    }
  }
}<p>この例では、「タイトル」フィールドのブースト係数は 3 であり、検索スコアの決定において「説明」フィールドよりも 3 倍重要になります。</p><h3>4. 異なるブースト係数を持つクエリを組み合わせる</h3><p>bool クエリを使用して、異なるブースト係数を持つ複数のクエリを組み合わせることもできます。これにより、検索結果の各フィールドの重要性を微調整できます。以下は、「title」フィールドと「description」フィールドに異なるブースト係数を適用したブールクエリの例です。</p>{
  "query": {
    "bool": {
      "should": [
        {"match": {"title": {"query": "example", "boost": 3}}},
        {"match": {"description": {"query": "example", "boost": 1}}}
      ]
    }
  }
}<p>この例では、「タイトル」フィールドのブースト係数は 3 ですが、「説明」フィールドのブースト係数は 1 です。</p><h2>まとめ</h2><p>Elasticsearch での 2 つのフィールドによる検索は、マルチマッチ クエリ、ブール クエリ、クエリ時フィールド ブースティングなどの高度な手法を使用して実現できます。これらの技術を組み合わせることで、ユーザーにとってより正確で関連性の高い検索結果を作成できます。さまざまなクエリの組み合わせとブースト係数を試して、特定のユースケースに最適な検索構成を見つけます。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-search-by-two-fields</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-search-by-two-fields</guid>
    <category><![CDATA[基本]]></category>
    <category><![CDATA[Query DSL]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltda47d75430c4fa7c/6a17f5cae3179149242d5963/d5d04bbcfc3925f48f3487ea4c7e0dd2205316d0-720x420.jpg" length="0" type="image/jpeg"/>
    <pubDate>Wed, 30 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[ユースケースにBetter Binary Quantization (BBQ)を実装する方法]]></title>
    <description><![CDATA[ユースケースで Better Binary Quantization (BBQ) を実装する理由とその方法について説明します。]]></description>
    <content:encoded><![CDATA[<p>ベクトル検索は、テキストのセマンティック検索や、画像、ビデオ、オーディオの類似性検索を実装する際の基盤を提供します。ベクトル検索では、ベクトルはデータの数学的表現であり、そのサイズは膨大で、場合によっては遅くなることがあります。Better Binary Quantization (以下、BBQ と呼びます) は、ベクトルの圧縮方法として機能します。これにより、ベクトルを縮小して検索と処理を高速化しながら、適切な一致を見つけることができます。この記事では、BBQ と、ベクトルを自動的に再スコアリングする量子化インデックスにのみ使用可能なフィールドである rescore_vector について説明します。</p><p>この記事で説明したすべての完全なクエリと出力は<a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/how-and-why-bbq">、Elasticsearch Labs コード リポジトリ</a>で確認できます。</p><h2>ユースケースで Better Binary Quantization (BBQ) を実装する理由は何ですか?</h2>注: BBQ の背後にある数学の仕組みを詳しく理解するには、以下の<a href="https://www.elastic.co/jp/search-labs/blog/bbq-implementation-into-use-case#further-learning">「さらに学ぶ」セクション</a>をご覧ください。このブログでは、実装に重点を置いています。<p>数学は興味深いものですが、ベクトル検索がなぜ正確であり続けるのかを完全に理解したい場合には重要です。結局のところ、現在のベクトル検索アルゴリズムではデータの読み取り速度によって制限されることが判明しているため、これはすべて圧縮に関することです。したがって、そのデータすべてをメモリに収めることができれば、ストレージから読み取る場合と比べて速度が大幅に向上します (<a href="https://sre.google/static/pdf/rule-of-thumb-latency-numbers-letter.pdf">メモリは SSD よりも約 200 倍高速です</a>)。</p><p>いくつか留意すべき点があります:</p><ul><li><p><a href="https://arxiv.org/pdf/1603.09320">HNSW</a> (Hierarchical Navigable Small World) などのグラフベースのインデックスは、ベクター検索では最も高速です。</p><ul><li><p>HNSW: 効率的な高次元類似性検索を可能にする多層グラフ構造を構築する近似最近傍検索アルゴリズム。</p></li></ul></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt760bd95c206bfa8f/6a17e2ad505ac393f7ad8a95/590f3b3c72a76023a38a0436cd9ff90a9f80e936-1964x1262.png" alt="HNSW: 効率的な高次元類似性検索を可能にする多層グラフ構造を構築する近似最近傍検索アルゴリズム。" /><ul><li><p>HNSW の速度は、基本的にメモリ、または最悪の場合、ストレージからのデータ読み取り速度によって制限されます。</p><ul><li><p>理想的には、保存されているすべてのベクトルをメモリにロードできるようにする必要があります。</p></li></ul></li><li><p>埋め込みモデルは通常、浮動小数点数ごとに 4 バイトの float32 精度のベクトルを生成します。</p></li><li><p>そして最後に、ベクトルや次元の数によっては、すべてのベクトルを保存するためのメモリがすぐに不足する可能性があります。</p></li></ul><p>これを当然のこととして考えると、それぞれが数百、数千の次元を持つ可能性のある数百万、数十億のベクトルを取り込み始めると、すぐに問題が発生することがわかります。「<a href="https://www.elastic.co/jp/search-labs/blog/bbq-implementation-into-use-case#approximate-numbers-on-the-compression-ratios">圧縮率のおおよその数値</a>」というセクションでは、おおよその数値が示されています。</p><h2>始めるには何が必要ですか?</h2><p>始めるには、次のものが必要です。</p><ul><li><p>Elastic Cloud またはオンプレミスを使用している場合は、Elasticsearch のバージョン 8.18 以降が必要になります。BBQ は 8.16 で導入されましたが、この記事では 8.18 で導入された<code>vector_rescore</code>使用します。</p></li><li><p>さらに、クラスター内に<a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/ml-settings.html">機械学習 (ML) ノード</a>があることも確認する必要があります。(注: モデルをロードするには最低 4 GB の ML ノードが必要ですが、完全な本番環境のワークロードには、はるかに大きなノードが必要になる可能性があります。)</p></li><li><p>Serverless を使用している場合は、ベクターに最適化されたインスタンスを選択する必要があります。</p></li><li><p>また、ベクター データベースに関する基本的な知識も必要になります。Elastic のベクトル検索の概念にまだ慣れていない場合は、まず次のリソースを確認することをお勧めします。</p><ul><li><p><a href="https://www.elastic.co/jp/search-labs/blog/elastic-vector-database-practical-example">弾性ベクトルデータベースのナビゲート</a></p></li><li><p><a href="https://www.elastic.co/jp/blog/retrieval-augmented-generation-explained">検索拡張生成の背後にある大きなアイデア</a></p></li></ul></li></ul><h2>より良いバイナリ量子化（BBQ）実装</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18df00df95ff2ca7/6a17e2af414c6411989450df/4d388078495566f0527e931e0c2e38facdce83c6-1503x748.png" alt="Elasticsearch バーベキュー実装。" /><p>このブログをシンプルに保つために、組み込み関数が利用可能な場合はそれを使用します。この場合、機械学習ノード上の Elasticsearch 内で直接実行される<a href="https://www.elastic.co/jp/guide/en/machine-learning/8.17/ml-nlp-e5.html"><code>.multilingual-e5-small</code></a>ベクトル埋め込みモデルがあります。<code>text_embedding</code>モデルを、任意の埋め込みツール ( <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/infer-service-openai.html">OpenAI</a> 、 <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/infer-service-google-ai-studio.html">Google AI Studio</a> 、 <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/infer-service-cohere.html">Cohere</a>など) に置き換えることができることに注意してください。希望するモデルがまだ統合されていない場合は、<a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/bring-your-own-vectors.html">独自の密なベクトル埋め込みも使用</a>できます。</p><p>まず、特定のテキストのベクトルを生成するための推論エンドポイントを作成する必要があります。これらのコマンドはすべて、Kibana <a href="https://www.elastic.co/jp/guide/en/kibana/8.18/console-kibana.html">Dev Tools コンソール</a>から実行します。このコマンドは<code>.multilingual-e5-small</code>をダウンロードします。まだ存在しない場合はエンドポイントが設定されます。実行には 1 分ほどかかる場合があります。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/01-create-an-inference-endpoint-output.json">01-create-an-inference-endpoint-output.json</a>で確認できます。 </p>PUT _inference/text_embedding/my_e5_model
{
  "service": "elasticsearch",
  "service_settings": {
    "num_threads": 1,
    "model_id": ".multilingual-e5-small",
    "adaptive_allocations": {
      "enabled": true,
      "min_number_of_allocations": 1
    }
  }
}<p>これが返されると、モデルが設定され、次のコマンドを使用してモデルが期待どおりに動作するかどうかをテストできます。期待される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/02-embed-text-output.json">02-embed-text-output.json</a>で確認できます。</p>POST _inference/text_embedding/my_e5_model
{
  "input": "my awesome piece of text"
}<p>トレーニング済みのモデルがどのノードにも割り当てられないという問題が発生した場合は、モデルを手動で起動する必要がある場合があります。</p>POST _ml/trained_models/.multilingual-e5-small/deployment/_start<p>ここで、埋め込みモデルからの出力と一致するように、標準テキスト フィールド ( <code>my_field</code> ) と 384 次元の密なベクトル フィールド ( <code>my_vector</code> ) の 2 つのプロパティを持つ新しいマッピングを作成しましょう。<code>index_options.type to bbq_hnsw</code>もオーバーライドします。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/03-create-byte-qauntized-index-output.json">03-create-byte-qauntized-index-output.json</a>で確認できます。</p>PUT bbq-my-byte-quantized-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "bbq_hnsw"
        }
      }
    }
  }
}<p>Elasticsearch がベクトルを生成するようにするには、 <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/ingest.html">Ingest Pipeline</a>を利用できます。このパイプラインには、エンドポイント ( <code>model_id</code> )、ベクトルを作成する<code>input_field</code> 、およびそれらのベクトルを格納する<code>output_field</code>の 3 つが必要です。以下の最初のコマンドは、内部で<a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/current/inference-apis.html">推論サービス</a>を使用する推論取り込みパイプラインを作成し、2 番目のコマンドはパイプラインが正しく動作していることをテストします。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/04-create-and-simulate-ingest-pipeline-output.json">04-create-and-simulate-ingest-pipeline-output.json</a>で確認できます。</p>PUT _ingest/pipeline/my_inference_pipeline
{
  "processors": [
    {
      "inference": {
        "model_id": "my_e5_model",
        "input_output": [
          {
            "input_field": "my_field",
            "output_field": "my_vector"
          }
        ]
      }
    }
  ]
}

POST _ingest/pipeline/my_inference_pipeline/_simulate
{
  "docs": [
    {
      "_source": {
        "my_field": "my awesome text field"
      }
    }
  ]
}<p>これで、以下の最初の 2 つのコマンドを使用してドキュメントを追加し、3 番目のコマンドで検索が機能することをテストする準備が整いました。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/05-bbq-index-output.json">05-bbq-index-output.json</a>で確認できます。</p>PUT bbq-my-byte-quantized-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT bbq-my-byte-quantized-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p><a href="https://www.elastic.co/jp/search-labs/blog/better-binary-quantization-lucene-elasticsearch#lucene-benchmarking">この投稿</a>で推奨されているように、圧縮の利点を活用しながら高い再現精度を維持するのに役立つため、大量のデータに拡張する場合は、再スコアリングとオーバーサンプリングが推奨されます。Elasticsearch バージョン 8.18 以降では、 <a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.18/knn-search.html#dense-vector-knn-search-rescoring">rescore_vector</a>を使用してこの方法で実行できます。予想される出力は、Outputs フォルダー内のファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/06-bbq-search-8-18-output.json">06-bbq-search-8-18-output.json</a>にあります。</p>GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "rescore_vector": {
              "oversample": 3
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p>これらのスコアは、生データで得られるスコアと比べてどうでしょうか?上記のすべてを<code>index_options.type: hnsw</code>を使ってもう一度実行すると、スコアが非常に似ていることがわかります。予想される出力は、Outputs フォルダーのファイル<a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/07-raw-vector-output.json">07-raw-vector-output.json</a>で確認できます。</p>PUT my-raw-vector-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "hnsw"
        }
      }
    }
  }
}

PUT my-raw-vector-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT my-raw-vector-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET my-raw-vector-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<h2>圧縮比のおおよその数値</h2><p>ベクトル検索を使用する場合、ストレージとメモリの要件がすぐに大きな課題になる可能性があります。次の内訳は、さまざまな量子化手法によってベクター データのメモリ フットプリントがいかに劇的に削減されるかを示しています。</p><p>ベクトル（V）</p><p>寸法（D）</p><p>生（V x D x 4）</p><p>int8 (V x (D x 1 + 4))</p><p>int4 (V x (D x 0.5 + 4))</p><p>バーベキュー（V×（D×0.125+4））</p><p>10,000,000</p><p>384</p><p>14.31GB</p><p>3.61GB</p><p>1.83GB</p><p>0.58GB</p><p>50,000,000</p><p>384</p><p>71.53GB</p><p>18.07GB</p><p>9.13GB</p><p>2.89GB</p><p>1億</p><p>384</p><p>143.05GB</p><p>36.14GB</p><p>18.25GB</p><p>5.77GB</p><h2>まとめ</h2><p>BBQ は、精度を犠牲にすることなくベクター データを圧縮するために適用できる最適化です。これはベクトルをビットに変換することで機能し、データを効果的に検索できるようにし、AI ワークフローを拡張して検索を高速化し、データ ストレージを最適化できるようにします。</p><h2>さらなる学習</h2><p>バーベキューについてさらに詳しく知りたい場合は、次のリソースをぜひチェックしてください。</p><ul><li><p><a href="https://www.elastic.co/jp/search-labs/blog/better-binary-quantization-lucene-elasticsearch">LuceneとElasticsearchにおけるバイナリ量子化（BBQ）</a></p></li><li><p><a href="https://www.elastic.co/jp/search-labs/blog/bit-vectors-elasticsearch-bbq-vs-pq">より良いバイナリ量子化（BBQ）と積量子化</a></p></li><li><p><a href="https://www.elastic.co/jp/search-labs/blog/optimized-scalar-quantization-elasticsearch">最適化されたスカラー量子化：さらに優れたバイナリ量子化</a></p></li><li><p><a href="https://www.youtube.com/watch?v=04NzMt2Nigc">より良いバイナリ量子化（BBQ）：バイトからBBQへ、より良いベクトル検索の秘密 by Ben Trent</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</guid>
    <category><![CDATA[Vector Database]]></category>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Sachin Frayne,Jessica Garson]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3dd0495b536b2615/6a17e2b0414c6488459450e3/66842055367cdd795532b01c167f2a4b03dc65e3-1200x628.png" length="0" type="image/png"/>
    <pubDate>Wed, 23 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch ヒープサイズの使用量と JVM ガベージコレクション]]></title>
    <description><![CDATA[Elasticsearch のヒープ サイズの使用と JVM ガベージ コレクションについて説明します。ベスト プラクティスや、ヒープ メモリの使用量が高すぎる場合や JVM のパフォーマンスが最適でない場合の問題を解決する方法も説明します。]]></description>
    <content:encoded><![CDATA[<p>ヒープ サイズは、Elasticsearch ノードの Java 仮想マシンに割り当てられる RAM の量です。</p><p>バージョン 7.11 以降、Elasticsearch はデフォルトで、ノードのロールと合計メモリに基づいて JVM ヒープ サイズを自動的に設定します。ほとんどの運用環境では、デフォルトのサイズ設定を使用することをお勧めします。ただし、JVM ヒープ サイズを手動で設定する場合は、一般的なルールとして、-Xms と -Xmx を同じ値に設定する必要があります。これは、使用可能な RAM の合計の 50% で、最大 (約) 31 GB になります。</p><p>ヒープ サイズを大きくすると、インデックス作成と検索操作に使用できるメモリがノードに多く割り当てられます。ただし、ノードにはキャッシュ用のメモリも必要なので、50% を使用すると 2 つのメモリのバランスが適切に保たれます。同じ理由から、本番環境では、Elasticsearch と同じノードで他のメモリを大量に消費するプロセスを使用することは避けてください。</p><p>通常、ヒープ使用量は鋸歯状のパターンに従い、使用されている最大ヒープの約 30 ～ 70% の間を変動します。これは、ガベージ コレクション プロセスによってメモリが再び解放されるまで、JVM がヒープ使用率を着実に増加させるためです。ガベージ コレクション プロセスが追いつかない場合、ヒープ使用率が高くなります。ヒープ使用量が高いことを示す指標は、ガベージ コレクションでヒープ使用量を約 30% まで削減できない場合です。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt03908d8eea824755/6a17dbe63e03d71e314f2b3e/0a17a67cc589a3c1fbf9e918eadc119df7bd7619-858x278.png" alt="" /><p>上の画像では、JVM ヒープの通常のノコギリ波を見ることができます。</p><p>また、ガベージ コレクションには、若い GC と古い GC の 2 種類があることもわかります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0d527a7905c78a45/6a17dbe84b055d09484320c2/8df5c24c4894404de4617be7a13683c9027d607d-875x281.png" alt="" /><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt681db7f60d9dbe40/6a17dbe97f6f152b9bc099f0/e01eb2537310b052580411153b8eddc187d97687-890x264.png" alt="" /><p>正常な JVM では、ガベージ コレクションは理想的には次の条件を満たす必要があります。</p><ul><li><p>Young GC は迅速に処理されます (50 ミリ秒以内)。</p></li><li><p>Young GC は頻繁に実行されません (約 10 秒)。</p></li><li><p>古い GC はすぐに処理されます (1 秒以内)。</p></li><li><p>古い GC は頻繁に実行されません (10 分に 1 回以上)。</p></li></ul><h3><strong>ヒープメモリ使用量が高すぎる場合やJVMパフォーマンスが最適でない場合の解決方法</strong></h3><p>ヒープ メモリの使用量が増える理由はさまざまです。</p><h4><strong>オーバーシャーディング</strong></h4><p>オーバーシャーディングに関するドキュメントは<a href="https://www.elastic.co/docs/deploy-manage/production-guidance/optimize-performance/size-shards#sizing-shard-guidelines">ここを</a>参照してください。</p><h4><strong>大規模な集約サイズ</strong></h4><p>集約サイズが大きくなるのを避けるには、クエリ内の集約バケットの数 (サイズ) を最小限に抑えます。</p>GET /_search
{
   "aggs" : {
       "products" : {
           "terms" : {
               "field" : "product",
               "size" : 5
                          }
       }
   }
}<p>低速クエリ ログ (スロー ログ) を使用し、次のように特定のインデックスに実装することができます。</p>PUT /my_index/_settings
{
   "index.search.slowlog.threshold.query.warn": "10s",
   "index.search.slowlog.threshold.query.info": "5s",
   "index.search.slowlog.threshold.query.debug": "2s",
   "index.search.slowlog.threshold.query.trace": "500ms",
   "index.search.slowlog.threshold.fetch.warn": "1s",
   "index.search.slowlog.threshold.fetch.info": "800ms",
   "index.search.slowlog.threshold.fetch.debug": "500ms",
   "index.search.slowlog.threshold.fetch.trace": "200ms",
   "index.search.slowlog.level": "info"
}<p>結果を返すのに長い時間がかかるクエリは、リソースを大量に消費するクエリである可能性が高くなります。</p><h4><strong>バルクインデックスのサイズが大きすぎる</strong></h4><p>大きなリクエストを送信する場合、ヒープ消費量が多くなる原因となる可能性があります。一括インデックス要求のサイズを小さくしてみてください。</p><h4><strong>マッピングの問題</strong></h4><p>特に、「fielddata: true」を使用する場合、これが JVM ヒープの主要なユーザーになる可能性があります。</p><h4><strong>ヒープサイズが正しく設定されていません</strong></h4><p>ヒープ サイズは次のように手動で定義できます。</p><p>環境変数の設定:</p>ES_JAVA_OPTS="-Xms2g -Xmx2g"<p>Elasticsearch 構成ディレクトリ内の jvm.options ファイルを編集します。</p>-Xms2g
-Xmx2g<p>環境変数の設定はファイルの設定よりも優先されます。</p><p>設定を有効にするにはノードを再起動する必要があります。</p><h4><strong>JVM の新しい比率が正しく設定されていません</strong></h4><p>Elasticsearch はデフォルトでこの値を設定するため、通常はこれを設定する必要はありません。このパラメータは、JVM 内の「新世代」オブジェクトと「旧世代」オブジェクトに使用可能なスペースの比率を定義します。</p><p>古い GC が非常に頻繁に発生していることがわかった場合は、Elasticsearch 構成ディレクトリの jvm.options ファイルでこの値を具体的に設定してみてください。</p>-XX:NewRatio=3<h3><strong>大規模な Elasticsearch クラスターでヒープサイズの使用量と JVM ガベージコレクションを管理するためのベストプラクティスは何ですか?</strong></h3><p>大規模な Elasticsearch クラスターでヒープ サイズの使用量と JVM ガベージ コレクションを管理するためのベスト プラクティスは、ヒープ サイズが使用可能な RAM の最大 50% に設定され、JVM ガベージ コレクション設定が特定のユース ケースに合わせて最適化されていることを確認することです。クラスターが最適に実行されていることを確認するには、ヒープ サイズとガベージ コレクション メトリックを監視することが重要です。具体的には、JVM ヒープ サイズ、ガベージ コレクション時間、ガベージ コレクションの一時停止を監視することが重要です。さらに、ガベージ コレクション サイクルの数とガベージ コレクションに費やされた時間を監視することも重要です。これらのメトリックを監視することで、ヒープ サイズやガベージ コレクションの設定に関する潜在的な問題を特定し、必要に応じて修正措置を講じることができます。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-heap-size-jvm-garbage-collection</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-heap-size-jvm-garbage-collection</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltc58290fbc9f4efb9/6a1705f97d8d67cae970e632/b162c28623b9070fd1980bcd891b9dd1e868f2f0-720x421.jpg" length="0" type="image/jpeg"/>
    <pubDate>Tue, 22 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearchでプライマリシャード数を増やす方法]]></title>
    <description><![CDATA[最適なシャードスケーリングを実現するために、分割APIと再インデックスAPIを使用してElasticsearchのプライマリシャード数を増やす方法を学びます。]]></description>
    <content:encoded><![CDATA[<p>既存のインデックスのプライマリ シャード数を増やすことはできません。つまり、プライマリ シャード数を増やす場合は、インデックスを再作成する必要があります。このような状況で一般的に使用される方法は 2 つあります。_reindex API と _split API です。</p><p>_split API は、多くの場合、_reindex API よりも高速な方法です。両方の操作の前に<strong>インデックス作成を</strong><strong>停止する必要があります</strong>。そうしないと、source_index と target_index のドキュメント数が異なります。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt46dd6abe0e6fe1eb/6a17e368148009d6a7b486d3/aa0ae010c2f5691ca00440fb453ed6b47bacd24f-1200x628.png" alt="Elasticsearchのシャード数を増やすためにインデックスを再作成" /><h2>方法1 – 分割APIを使用する</h2><p>分割 API は、設定をコピーし、既存のインデックスをマッピングすることで、必要な数のプライマリ シャードを持つ新しいインデックスを作成するために使用されます。作成時に必要なプライマリ シャードの数を設定できます。分割 API を実装する前に、次の設定を確認する必要があります。</p><ol><li><p>ソース インデックスは読み取り専用である必要があります。これは、インデックス作成プロセスを停止する必要があることを意味します。</p></li><li><p>ターゲット インデックス内のプライマリ シャードの数は、ソース インデックス内のプライマリ シャードの数の倍数である必要があります。たとえば、ソース インデックスに 5 つのプライマリ シャードがある場合、ターゲット インデックスのプライマリ シャードを 10、15、20 などに設定できます。</p></li></ol><p>注: プライマリ シャード番号のみを変更する必要がある場合は、再インデックス API よりもはるかに高速な分割 API が推奨されます。</p><h3>分割APIの実装</h3><p>テストインデックスを作成します。</p>POST test_split_source/_doc
{
  "test": "test"
}<p>分割するには、ソース インデックスが読み取り専用である必要があります。</p>PUT test_split_source/_settings
{
  "index.blocks.write": true
}<p>設定とマッピングはソース インデックスから自動的にコピーされます。</p>POST /test_split_source/_split/test_split_target
{
  "settings": {
    "index.number_of_shards": 3
  }
}<p>進捗状況は以下で確認できます:</p>GET _cat/recovery/test_split_target?v&amp;h=index,shard,time,stage,files_percent,files_total<p>設定とマッピングはソース インデックスからコピーされるため、ターゲット インデックスは読み取り専用になります。ターゲット インデックスへの書き込み操作を有効にしましょう。</p>PUT test_split_target/_settings
{
    "index.blocks.write": null
}<p>元のインデックスを削除する前に、ソース インデックスとターゲット インデックスの docs.count を確認します。</p>GET _cat/indices/test_split*?v&amp;h=index,pri,rep,docs.count<p>インデックス名とエイリアス名を同じにすることはできません。ソース インデックスを削除し、ソース インデックス名をターゲット インデックスのエイリアスとして追加する必要があります。</p>DELETE test_split_source
PUT /test_split_target/_alias/test_split_source<p><strong>test_split_source</strong>エイリアスを<strong>test_split_target</strong>インデックスに追加した後、次のようにテストする必要があります。</p>GET test_split_source
POST test_split_source/_doc
{
  "test": "test"
}<h2>方法2 – 再インデックスAPIを使用する</h2><p>Reindex API を使用して新しいインデックスを作成すると、任意の数のプライマリ シャード カウントを指定できます。意図した数のプライマリ シャードで新しいインデックスを作成した後、ソース インデックス内のすべてのデータをこの新しいインデックスに再インデックスできます。</p><p>分割 API 機能に加えて、再インデックス AP の ingest_pipeline を使用してデータを操作することもできます。取り込みパイプラインでは、フィルターに適合する指定されたフィールドのみがクエリを使用してターゲット インデックスにインデックス付けされます。データの内容は簡単なスクリプトを使用して変更でき、複数のインデックスを 1 つのインデックスにマージできます。</p><h3>再インデックスAPIの実装</h3><p>テストの再インデックスを作成します。</p>POST test_reindex_source/_doc
{
    "test": "test"
}<p>ソース インデックスから設定とマッピングをコピーします。</p>GET test_reindex_source<p>設定、マッピング、および必要なシャード数を使用してターゲット インデックスを作成します。</p>PUT test_reindex_target
{
  "mappings" : {},
  "settings": {
    "number_of_shards": 10,
    "number_of_replicas": 0,
    "refresh_interval": -1
  }
}<p>*注: number_of_replicas: 0 および refresh_interval: -1 を設定すると、再インデックスの速度が向上します。</p><p>再インデックスプロセスを開始します。requests_per_second=-1 および slices=auto を設定すると、再インデックス速度が調整されます。</p>POST _reindex?requests_per_second=-1&amp;slices=auto&amp;wait_for_completion=false
{
  "source": {
    "index": "test_reindex_source"
  },
  "dest": {
    "index": "test_reindex_target"
  }
}<p>再インデックス API を実行すると、task_id が表示されます。それをコピーして、_tasks API で確認します。</p>GET _tasks/&lt;task_id&gt;<p>再インデックスが完了したら設定を更新します。</p>PUT test_reindex_target/_settings
{
  "number_of_replicas": 1,
  "refresh_interval": "1s"
}<p>元のインデックスを削除する前に、ソース インデックスとターゲット インデックスの docs.count が同じであることを確認します。</p>GET _cat/indices/test_reindex_*?v&amp;h=index,pri,rep,docs.count<p>インデックス名とエイリアス名を同じにすることはできません。ソース インデックスを削除し、ソース インデックス名をターゲット インデックスのエイリアスとして追加します。</p>DELETE test_reindex_source
PUT /test_reindex_target/_alias/test_reindex_source<p>test_split_source エイリアスを test_split_target インデックスに追加した後、次のコマンドを使用してテストします。</p>GET test_reindex_source<h2>まとめ</h2><p>既存のインデックスのプライマリ シャード数を増やす場合は、新しいインデックスへの設定とマッピングを再作成する必要があります。これを行うには、主に reindex API と split API という 2 つの方法があります。どちらの方法を使用する前にも、アクティブなインデックス作成を停止する必要があります。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-increase-primary-shard-count</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-increase-primary-shard-count</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blta8aa774fc00d7233/6a17e223dbb4ff68b3fb5611/7034b76019a0cba52c25eda29fceb18afc96ed0b-720x420.png" length="0" type="image/png"/>
    <pubDate>Thu, 17 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Elasticsearch の異なるバージョン間およびクラスター間でデータを移行する方法]]></title>
    <description><![CDATA[Elasticsearch のバージョンとクラスター間でデータを転送する方法を検討します。]]></description>
    <content:encoded><![CDATA[<p>Elasticsearch クラスターをアップグレードする場合、新しい別のクラスターを作成し、古いクラスターから新しいクラスターにデータを転送する方が簡単な場合があります。これにより、ユーザーは、ダウンタイムやデータ損失のリスクなしに、すべてのアプリケーションを使用して新しいクラスター上のすべてのデータと構成をテストできるという利点が得られます。</p><p>このアプローチの欠点は、ハードウェアの重複が必要となり、すべてのデータをスムーズに転送および同期する際に困難が生じる可能性があることです。</p><p>アプリケーションをあるデータ センターから別のデータ センターに移行する必要がある場合にも、同様の手順を実行する必要がある場合があります。</p><p>この記事では、Elasticsearch クラスター間でデータを転送する 3 つの方法について詳しく説明します。</p><p><strong>Elasticsearch クラスター間でデータを移行するにはどうすればよいですか?</strong></p><p>Elasticsearch クラスター間でデータを転送する方法は 3 つあります。</p><ol><li><p><a href="https://www.elastic.co/jp/search-labs/blog/elasticsearch-migrate-data-versions-clusters#1.-reindexing-data-from-a-remote-cluster">リモートクラスタからの再インデックス</a></p></li><li><p><a href="https://www.elastic.co/jp/search-labs/blog/elasticsearch-migrate-data-versions-clusters#2.-transferring-data-using-snapshots">スナップショットを使用したデータ転送</a></p></li><li><p><a href="https://www.elastic.co/jp/search-labs/blog/elasticsearch-migrate-data-versions-clusters#3.-transferring-data-using-logstash">Logstash を使用したデータ転送</a></p></li></ol><p>通常、スナップショットを使用するのが、データを転送する最も高速かつ信頼性の高い方法です。ただし、スナップショットは同等以上のバージョンのクラスターにのみ復元でき、メジャー バージョンが 1 つ以上異なるクラスターには復元できないことに注意してください。つまり、6.x スナップショットを 7.x クラスターに復元することはできますが、8.x クラスターには復元できません。</p><p>メジャー バージョンを 1 つ以上増やす必要がある場合は、インデックスを再作成するか、Logstash を使用する必要があります。</p><p>ここで、Elasticsearch クラスター間でデータを転送するための 3 つのオプションをそれぞれ詳しく見ていきましょう。</p><h2>1. リモートクラスタからのデータの再インデックス</h2><p>再インデックスを開始する前に、新しいクラスター上のすべてのインデックスに対して適切なマッピングを設定する必要があることに注意してください。そのためには、適切なマッピングを使用してインデックスを直接作成するか、インデックス テンプレートを使用する必要があります。</p><h3>リモートからの再インデックス - 設定が必要</h3><p>リモートから再インデックスを行うには、データを受信しているクラスターの elasticseearch.yml ファイルに以下の構成を追加する必要があります。Linux システムでは、このファイルは、通常、/etc/elasticsearch/elasticsearch.yml にあります。追加する構成は次のとおりです。</p>reindex.remote.whitelist: "192.168.1.11:9200"<p>SSL を使用している場合は、各ノードに CA 証明書を追加し、elasticsearch.yml 内の各ノードのコマンドに以下を含める必要があります。</p>reindex.ssl.certificate_authorities: “/path/to/ca.pem”<p>あるいは、SSL 検証を無効にするために、すべての Elasticsearch ノードに以下の行を追加することもできます。ただし、このアプローチは前のオプションほど安全ではないため、あまりお勧めできません。</p>reindex.remote.whitelist: "192.168.1.11:9200"
reindex.ssl.verification_mode: none
systemctl restart elasticsearch service <p>すべてのノードでこれらの変更を行い、ローリング再起動を実行する必要があります。その方法の詳細については、<a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/8.17/restart-cluster.html#restart-cluster-rolling">ガイド</a>をご覧ください。</p><h3>再インデックスコマンド</h3><p>elasticsearch.yml ファイルでリモート ホストを定義し、必要に応じて SSL 証明書を追加したら、以下のコマンドでデータの再インデックスを開始できます。</p>POST _reindex
{
  "source": {
    "remote": {
      "host": "http://192.168.1.11:9200",
      "username": "elastic",
      "password": "123456",
     "socket_timeout": "1m",
      "connect_timeout": "1m"

    },
    "index": "companydatabase"
  },
  "dest": {
    "index": "my-new-index-000001"
  }
}<p>その際、タイムアウト エラーが発生する可能性があるため、デフォルトに頼るのではなく、タイムアウトに余裕を持った値を設定すると便利な場合があります。</p><p>ここで、リモートから再インデックスするときに発生する可能性のあるその他の一般的なエラーを見てみましょう。</p><h3>リモートからの再インデックス時によくあるエラー</h3><h4>1. 再インデックスがホワイトリストに登録されていない</h4>{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "[192.168.1.11:9200] not whitelisted in reindex.remote.whitelist"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "[192.168.1.11:9200] not whitelisted in reindex.remote.whitelist"
  },
  "status": 400
}<p>このエラーが発生した場合は、上記のように Elasticsearch でリモート ホストの IP アドレスまたはノード名 DNS を定義しなかったか、Elasticsearch サービスの再起動を忘れたことを示しています。</p><p>Elasticsearch クラスターでこの問題を修正するには、リモート ホストをすべての Elasticsearch ノードに追加し、Elasticsearch サービスを再起動する必要があります。</p><h4>2. SSLハンドシェイク例外</h4>{
  "error": {
    "root_cause": [
      {
        "type": "s_s_l_handshake_exception",
        "reason": "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target"
      }
    ],
    "type": "s_s_l_handshake_exception",
    "reason": "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target",
    "caused_by": {
      "type": "validator_exception",
      "reason": "PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target",
      "caused_by": {
        "type": "sun_cert_path_builder_exception",
        "reason": "unable to find valid certification path to requested target"
      }
    }
  },
  "status": 500
}<p>このエラーは、上記のように elasticsearch.yml に reindex.ssl.certificate_authorities を追加するのを忘れたことを意味します。追加するには:</p>#elasticsearch.yml
reindex.ssl.certificate_authorities: "/path/to/ca.pem"<h2>2. スナップショットを使用したデータ転送</h2><p>前述のように、スナップショットは同等以上のバージョンのクラスタにのみ復元でき、1つ以上のメジャーバージョンの違いがあるクラスタには復元できないことに注意してください。</p><p>メジャー バージョンを 1 つ以上増やす必要がある場合は、インデックスを再作成するか、Logstash を使用する必要があります。</p><p>スナップショットを介してデータを転送するには、次の手順が必要です。</p><p>ステップ 1. 最初の Elasticsearch クラスターにリポジトリ プラグインを追加する – スナップショットを介してクラスター間でデータを転送するには、新しいクラスターと古いクラスターの両方からリポジトリにアクセスできることを確認する必要があります。通常、AWS、Google、Azure などのクラウド ストレージ リポジトリがこれに最適です。スナップショットを撮るには、<a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/current/snapshot-restore.html">ガイド</a>を参照して、そこに記載されている手順に従ってください。</p><p>ステップ 2. Elasticsearch サービスを再起動します (ローリング再起動)。</p><p>ステップ 3. 最初の Elasticsearch クラスターのリポジトリを作成します。</p><p>ステップ 4 - リポジトリ プラグインを 2 番目の Elasticsearch クラスターに追加します。</p><p>ステップ 5 - リポジトリを 2 番目の Elasticsearch クラスターに読み取り専用として追加する - 最初の Elasticsearch クラスターを作成するときに実行したのと同じ手順を繰り返して、リポジトリを追加する必要があります。</p><p>重要な注意: 2 番目の Elasticsearch クラスターを同じ AWS S3 リポジトリに接続する場合は、リポジトリを読み取り専用リポジトリとして定義する必要があります。</p>PUT _snapshot/my_s3_repository
{
  "type": "s3",
  "settings": {
    "bucket": "my-analytic-data",
    "endpoint": "s3.eu-de.cloud-object-storage.appdomain.cloud",
    "readonly": "true"
  }
}<p>これは、同じスナップショットリポジトリ内で Elasticsearch のバージョンが混在するリスクを回避するために重要です。</p><p>ステップ 6 - 2 番目の Elasticsearch クラスターへのデータの復元 - 上記の手順を実行した後、データを復元して新しいクラスターに転送できます。新しいクラスターにデータを復元するには、<a href="https://www.elastic.co/jp/guide/en/elasticsearch/reference/current/snapshot-restore.html">この記事</a>に記載されている手順に従ってください。</p><h2>3. Logstash を使用したデータ転送</h2><p>logstash を使用してデータの転送を開始する前に、新しいクラスター上のすべてのインデックスに対して適切なマッピングを設定する必要があることに注意してください。そのためには、インデックスを直接作成するか、インデックス テンプレートを使用する必要があります。</p><p>2 つの Elasticsearch クラスター間でデータを転送するには、一時的な Logstash サーバーをセットアップし、それを使用して 2 つのクラスター間でデータを転送できます。小規模なクラスターの場合、2GB の RAM インスタンスで十分です。より大規模なクラスターの場合は、8GB の RAM を搭載した 4 コア CPU を使用できます。</p><p>Logstash のインストールに関するガイダンスについては、<a href="https://www.elastic.co/jp/guide/en/logstash/current/installing-logstash.html">こちらをご覧</a>ください。</p><h3>あるクラスターから別のクラスターにデータを転送するための Logstash 構成</h3><p>クラスター A からクラスター B に単一のインデックスをコピーするための基本構成は次のとおりです。</p>iinput
{
elasticsearch
      {
        hosts =&gt; ["192.168.1.11:9200"]
        index =&gt; "index_name"
       docinfo =&gt; true      
      }
}

output 
{
  elasticsearch {
        hosts =&gt; "https://192.168.1.12:9200"
        index =&gt; "index_name"
        
  }
}<p>セキュアな elasticsearch の場合は、以下の構成を使用できます。</p>input
{
  elasticsearch
      {
        hosts =&gt; ["192.168.1.11:9200"]
        index =&gt; "index_name"
        docinfo =&gt; true 
        user =&gt; "elastic"
        password =&gt; "elastic_password"
        ssl =&gt; true
        ssl_certificate_verification =&gt; false
            
      }
}

output 
{
  elasticsearch {
        hosts =&gt; "https://192.168.1.12:9200"
        index =&gt; "index_name"
        user =&gt; "elastic"
        password =&gt; "elastic_password"
        ssl =&gt; true
        ssl_certificate_verification =&gt; false
  }
}<h3>インデックスメタデータ</h3><p>上記のコマンドは、単一の名前付きインデックスに書き込みます。複数のインデックスを転送し、インデックス名を保持する場合は、Logstash 出力に次の行を追加する必要があります。</p>index =&gt; "%{[@metadata][_index]}"<p>また、ドキュメントの元の ID を保持したい場合は、以下を追加する必要があります。</p>document_id =&gt; "%{[@metadata][_id]}"<p>ドキュメント ID を設定するとデータ転送速度が大幅に低下することに注意してください。必要な場合にのみ元の ID を保持してください。</p><h2>更新の同期</h2><p>上記の方法はすべて比較的長い時間がかかり、プロセスが完了するまでに元のクラスターのデータが更新されている場合があります。</p><p>データ転送プロセス中に発生した可能性のある更新を同期できるようにするにはさまざまな戦略があり、そのプロセスを開始する前にこれらの問題について検討する必要があります。特に、次の点を考慮する必要があります。</p><ul><li><p>データ転送プロセスの開始以降に更新/追加されたデータを識別する方法は何ですか (例: データ内の「last_update_time」フィールド)?</p></li><li><p>最後のデータを転送するにはどのような方法を使用できますか?</p></li><li><p>記録が重複するリスクはありますか?通常は、使用している方法によって再インデックス中にドキュメント ID が既知の値に設定されない限り、存在します。</p></li></ul><p>更新の同期を有効にするさまざまな方法について以下に説明します。</p><h3>1. 待ち行列システムの使用</h3><p>一部の取り込み/更新システムでは、過去 x 日間に受信したデータの変更を「再生」できるキューを使用します。これにより、実行された変更を同期する手段が提供される場合があります。 </p><h3>2. リモートから再インデックス</h3><p>「last_update_time」が x 日前を超えるすべてのアイテムに対して、再インデックス処理を繰り返します。これを行うには、再インデックス リクエストに「クエリ」パラメータを追加します。</p><h3>3. ログスタッシュ</h3><p>Logstash 入力では、「last_update_time」が x 日前を超えるすべての項目をフィルターするクエリを追加できます。ただし、document_id を設定していない限り、このプロセスでは非時系列データに重複が発生します。</p><h3>4. スナップショット</h3><p>インデックスの一部だけを復元することはできないため、データ転送プロセスの実行以降に行われた変更を更新するには、上で説明した他のデータ転送方法のいずれか (またはスクリプト) を使用する必要があります。</p><p>ただし、スナップショットの復元は再インデックス/Logstash よりもはるかに高速なプロセスであるため、スナップショットの転送中に更新を短時間一時停止して、問題を完全に回避できる可能性があります。</p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-migrate-data-versions-clusters</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-migrate-data-versions-clusters</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Kofi Bartlett]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltfc041ebca11476c6/6a16f70560084b31b93c4344/01fde3b1d714f12bf8673140c9f2f940d443de31-1440x823.jpg" length="0" type="image/jpeg"/>
    <pubDate>Mon, 14 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[同義語APIを使用して同義語を自動化し、アップロードする方法]]></title>
    <description><![CDATA[LLM を使用して同義語を自動的に識別および生成し、用語をプログラムで Elasticsearch 同義語 API に読み込むことができる方法について説明します。]]></description>
    <content:encoded><![CDATA[<p>効率的なユーザー エクスペリエンスを提供するには、検索結果の品質を向上させることが不可欠です。検索を最適化する 1 つの方法は、同義語を通じて検索対象の用語を自動的に拡張することです。これにより、クエリをより広範囲に解釈できるようになり、言語のバリエーションをカバーして結果の一致が向上します。</p><p>このブログでは、大規模言語モデル (LLM) を使用して同義語を自動的に識別および生成し、これらの用語をプログラムで Elasticsearch の同義語 API に読み込むことができる方法について説明します。</p><h2>同義語はいつ使用すればよいですか?</h2><p>同義語を使用すると、ベクトル検索に比べて高速かつコスト効率の高いソリューションになります。埋め込みに関する深い知識や複雑なベクトル取り込みプロセスを必要としないため、実装はより簡単です。</p><p>さらに、ベクトル検索ではインデックス作成と検索を埋め込むために大きなストレージ容量とメモリが必要になるため、リソースの消費量が少なくなります。</p><p>もう一つの重要な側面は、検索の地域化です。同義語を使用すると、現地の言語や習慣に応じて用語を適応させることができます。これは、埋め込みが地域的な表現や国固有の用語と一致しない可能性がある場合に役立ちます。たとえば、一部の単語や頭字語は地域によって意味が異なる場合がありますが、現地のユーザーにとっては当然同義語として扱われます。ブラジルでは、これはかなり一般的です。「アバカシ」と「アナナス」は同じ果物（パイナップル）ですが、北東部の一部の地域では後者の用語の方が一般的に使用されています。同様に、南東部でよく知られている「pão francês」は、北東部では「pão careca」として知られている場合があります。</p><h2>LLM を使用して同義語を生成するにはどうすればよいでしょうか?</h2><p>同義語を自動的に取得するには、用語のコンテキストを分析して適切なバリエーションを提案する LLM を使用できます。このアプローチにより、同義語を動的に拡張できるため、固定辞書に依存せずに、より広範で正確な検索が可能になります。</p><p>このデモでは、LLM を使用して電子商取引製品の同義語を生成します。多くの検索では、検索語句のバリエーションにより、結果がほとんど返されないか、まったく返されません。同義語を使用すると、この問題は解決できます。たとえば、「スマートフォン」を検索すると、さまざまな種類の携帯電話が検索されるため、ユーザーは探している製品を見つけることができます。</p><h3>要件</h3><p>始める前に、環境を設定し、必要な依存関係を定義する必要があります。Elastic が提供するソリューションを使用して、 <a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html">Elasticsearch と Kibana を Docker でローカルに実行します</a>。コードは Python v3.9.6 で記述され、次の依存関係があります。</p>pip install openai==1.59.8 elasticsearch==8.15.1<h3>製品インデックスの作成</h3><p>最初は、同義語をサポートしない製品のインデックスを作成します。これにより、クエリを検証し、同義語を含むインデックスと比較できるようになります。</p><p>インデックスを作成するには、Kibana DevTools で次のコマンドを使用して製品データセットを一括ロードします。</p>POST _bulk
{"index": {"_index": "products", "_id": 10001}}
{"category": "Electronics", "name": "iPhone 14 Pro"}
{"index": {"_index": "products", "_id": 10007}}
{"category": "Electronics", "name": "MacBook Pro 16-inch"}
{"index": {"_index": "products", "_id": 10013}}
{"category": "Electronics", "name": "Samsung Galaxy Tab S8"}
{"index": {"_index": "products", "_id": 10037}}
{"category": "Electronics", "name": "Apple Watch Series 8"}
{"index": {"_index": "products", "_id": 10049}}
{"category": "Electronics", "name": "Kindle Paperwhite"}
{"index": {"_index": "products", "_id": 10067}}
{"category": "Electronics", "name": "Samsung QLED 4K TV"}
{"index": {"_index": "products", "_id": 10073}}
{"category": "Electronics", "name": "HP Spectre x360 Laptop"}
{"index": {"_index": "products", "_id": 10079}}
{"category": "Electronics", "name": "Apple AirPods Pro"}
{"index": {"_index": "products", "_id": 10115}}
{"category": "Electronics", "name": "Amazon Echo Show 10"}
{"index": {"_index": "products", "_id": 10121}}
{"category": "Electronics", "name": "Apple iPad Air"}
{"index": {"_index": "products", "_id": 10127}}
{"category": "Electronics", "name": "Apple AirPods Max"}
{"index": {"_index": "products", "_id": 10151}}
{"category": "Electronics", "name": "Sony WH-1000XM4 Headphones"}
{"index": {"_index": "products", "_id": 10157}}
{"category": "Electronics", "name": "Google Pixel 6 Pro"}
{"index": {"_index": "products", "_id": 10163}}
{"category": "Electronics", "name": "Apple MacBook Air"}
{"index": {"_index": "products", "_id": 10181}}
{"category": "Electronics", "name": "Google Pixelbook Go"}
{"index": {"_index": "products", "_id": 10187}}
{"category": "Electronics", "name": "Sonos Beam Soundbar"}
{"index": {"_index": "products", "_id": 10199}}
{"category": "Electronics", "name": "Apple TV 4K"}
{"index": {"_index": "products", "_id": 10205}}
{"category": "Electronics", "name": "Samsung Galaxy Watch 4"}
{"index": {"_index": "products", "_id": 10211}}
{"category": "Electronics", "name": "Apple MacBook Pro 16-inch"}
{"index": {"_index": "products", "_id": 10223}}
{"category": "Electronics", "name": "Amazon Echo Dot (4th Gen)"}<h3>LLMによる同義語の生成</h3><p>このステップでは、LLM を使用して同義語を動的に生成します。これを実現するために、OpenAI API を統合し、適切なモデルとプロンプトを定義します。LLM は製品のカテゴリと名前を受け取り、同義語が文脈的に適切であることを確認します。</p>import json
import logging

from openai import OpenAI

def call_gpt(prompt, model):
    try:
        logging.info("generate synonyms by llm...")
        response = client.chat.completions.create(
            model=model,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.7,
            max_tokens=1000
        )
        content = response.choices[0].message.content.strip()
        return content
    except Exception as e:
        logging.error(f"Failed to use model: {e}")
        return None

def generate_synonyms(category, products):
   synonyms = {}

   for product in products:
       prompt = f"You are an expert in generating synonyms for products. Based on the category and product name provided, generate synonyms or related terms. Follow these rules:\n"
       prompt += "1. **Format**: The first word should be the main item (part of the product name, excluding the brand), followed by up to 3 synonyms separated by commas.\n"
       prompt += "2. **Exclude the brand**: Do not include the brand name in the synonyms.\n"
       prompt += "3. **Maximum synonyms**: Generate a maximum of 3 synonyms per product.\n\n"
       prompt += f"The category is: **{category}**, and the product is: **{product}**. Return only the synonyms in the requested format, without additional explanations."

       response = call_gpt(prompt, "gpt-4o")
       synonyms[product] = response

   return synonyms<p>作成された製品インデックスから、「エレクトロニクス」カテゴリ内のすべてのアイテムを取得し、その名前を LLM に送信します。予想される出力は次のようになります。</p>{
  "iPhone 14 Pro": ["iPhone", "smartphone", "mobile", "handset"],
  "MacBook Pro 16-inch": ["MacBook", "Laptop", "Notebook", "Ultrabook"],
  "Samsung Galaxy Tab S8": ["Tab", "Tablet", "Slate", "Pad"],
  "Bose QuietComfort 35 Headphones": ["Headphones", "earphones", "earbuds", "headset"]
}<p>生成された同義語は、Synonyms API を使用して Elasticsearch に登録できます。</p><h3>Synonyms API による同義語の管理</h3><p>シノニム API は、システム内でシノニム セットを直接管理する効率的な方法を提供します。各同義語セットは同義語ルールで構成され、検索では単語のグループが同等として扱われます。</p><p><strong>同義語セットの作成例</strong></p>PUT _synonyms/my-synonyms-set
{
  "synonyms_set": [
    {
      "id": "rule-1",
      "synonyms": "hello, hi"
    },
    {
      "synonyms": "bye, goodbye"
    }
  ]
}<p>
これにより、「my-synonyms-set」というセットが作成され、そこでは「hello」と「hi」が「bye」と「goodbye」と同様に同等として扱われます。</p><h2>製品カタログの同義語作成の実装</h2><p>以下は、同義語セットを構築して Elasticsearch に挿入するメソッドです。同義語ルールは、LLM によって提案された同義語のマッピングに基づいて生成されます。各ルールには、スラッグ形式の製品名に対応する ID と、LLM によって計算された同義語のリストがあります。</p>import json
import logging

from elasticsearch import Elasticsearch
from slugify import slugify

es = Elasticsearch(
    "http://localhost:9200",
    api_key="your_api_key"
)

def mount_synonyms(results):
   synonyms_set = [{"id": slugify(product), "synonyms": synonyms} for product, synonyms in
                   results.items()]

   try:
       response = es.synonyms.put_synonym(id="products-synonyms-set",
                                                 synonyms_set=synonyms_set)

       logging.info(json.dumps(response.body, indent=4))
       return response.body
   except Exception as e:
       logging.error(f"Error create synonyms: {str(e)}")
       return None<p>以下は、同義語セットを作成するためのリクエスト ペイロードです。</p>{
   "synonyms_set":[
      {
         "id": "iphone-14-pro",
         "synonyms": "iPhone, smartphone, mobile, handset"
      },
      {
         "id": "macbook-pro-16-inch",
         "synonyms": "MacBook, Laptop, Notebook, Computer"
      },
      {
         "id": "samsung-galaxy-tab-s8",
         "synonyms": "Tablet, Slate, Pad, Device"
      },
      {
         "id": "garmin-forerunner-945",
         "synonyms": "Forerunner, smartwatch, fitness watch, GPS watch"
      },
      {
         "id": "bose-quietcomfort-35-headphones",
         "synonyms": "Headphones, Earphones, Headset, Cans"
      }
   ]
}<p>クラスターにシノニム セットが作成されたら、次のステップに進み、定義したセットを使用してシノニムをサポートする新しいインデックスを作成します。</p><p>LLM によって生成された同義語と、Synonyms API によって定義された同義語セットの作成を含む完全な Python コードは次のとおりです。</p>import json
import logging

from elasticsearch import Elasticsearch
from openai import OpenAI
from slugify import slugify

logging.basicConfig(level=logging.INFO)

client = OpenAI(
   api_key="your-key",
)

es = Elasticsearch(
    "http://localhost:9200",
    api_key="your_api_key"
)


def call_gpt(prompt, model):
   try:
       logging.info("generate synonyms by llm...")
       response = client.chat.completions.create(
           model=model,
           messages=[{"role": "user", "content": prompt}],
           temperature=0.7,
           max_tokens=1000
       )
       content = response.choices[0].message.content.strip()
       return content
   except Exception as e:
       logging.error(f"Failed to use model: {e}")
       return None


def generate_synonyms(category, products):
   synonyms = {}

   for product in products:
       prompt = f"You are an expert in generating synonyms for products. Based on the category and product name provided, generate synonyms or related terms. Follow these rules:\n"
       prompt += "1. **Format**: The first word should be the main item (part of the product name, excluding the brand), followed by up to 3 synonyms separated by commas.\n"
       prompt += "2. **Exclude the brand**: Do not include the brand name in the synonyms.\n"
       prompt += "3. **Maximum synonyms**: Generate a maximum of 3 synonyms per product.\n\n"
       prompt += f"The category is: **{category}**, and the product is: **{product}**. Return only the synonyms in the requested format, without additional explanations."

       response = call_gpt(prompt, "gpt-4o")
       synonyms[product] = response

   return synonyms


def get_products(category):
   query = {
       "size": 50,
       "_source": ["name"],
       "query": {
           "bool": {
               "filter": [
                   {
                       "term": {
                           "category.keyword": category
                       }
                   }
               ]
           }
       }
   }
   response = es.search(index="products", body=query)

   if response["hits"]["total"]["value"] &gt; 0:
       product_names = [hit["_source"]["name"] for hit in response["hits"]["hits"]]
       return product_names
   else:
       return []


def mount_synonyms(results):
   synonyms_set = [{"id": slugify(product), "synonyms": synonyms} for product, synonyms in
                   results.items()]

   try:
       es_client = get_client_es()
       response = es_client.synonyms.put_synonym(id="products-synonyms-set",
                                                 synonyms_set=synonyms_set)

       logging.info(json.dumps(response.body, indent=4))
       return response.body
   except Exception as e:
       logging.error(f"Erro update synonyms: {str(e)}")
       return None


if __name__ == '__main__':
   category = "Electronics"
   products = get_products("Electronics")
   llm_synonyms = generate_synonyms(category, products)
   mount_synonyms(llm_synonyms)<h3>同義語サポート付きのインデックスの作成</h3><p>新しいインデックスが作成され、 <code>products</code>インデックスのすべてのデータが再インデックスされます。このインデックスは、以前に作成された<code>products-synonyms-set</code>を適用する<code>synonyms_filter</code>を使用します。</p><p>以下はシノニムを使用するように構成されたインデックス マッピングです。</p>PUT products_02
{
  "settings": {
    "analysis": {
      "filter": {
        "synonyms_filter": {
          "type": "synonym",
          "synonyms_set": "products-synonyms-set",
          "updateable": true
        }
      },
      "analyzer": {
        "synonyms_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": [
            "lowercase",
            "synonyms_filter"
          ]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "ID": {
        "type": "long"
      },
      "category": {
        "type": "keyword"
      },
      "name": {
        "type": "text",
        "analyzer": "standard",
        "search_analyzer": "synonyms_analyzer"
      }
    }
  }
}<h3><code>products</code>インデックスの再インデックス</h3><p>ここで、 <strong>Reindex API を</strong>使用して、 <code>products</code>インデックスからシノニムのサポートを含む新しい<code>products_02</code>インデックスにデータを移行します。Kibana DevTools で次のコードが実行されました。
</p>POST _reindex
{
  "source": {
    "index": "products"
  },
  "dest": {
    "index": "products_02"
  }
}<p>移行後、 <code>products_02</code>インデックスが作成され、構成された同義語セットを使用して検索を検証できるようになります。</p><h3>同義語による検索の検証</h3><p>2つのインデックス間の検索結果を比較してみましょう。両方のインデックスに対して同じクエリを実行し、結果を取得するために同義語が使用されているかどうかを検証します。</p><h4><code>products</code>インデックスで検索（同義語なし）</h4><p>Kibana を使用して検索を実行し、結果を分析します。「分析 &gt; 検出」メニューで、作成したインデックスのデータを視覚化するためのデータ ビューを作成します。</p><p>Discovery 内で、データ ビューをクリックし、名前とインデックス パターンを定義します。「 <strong>products</strong> 」インデックスでは、「 <strong>products</strong> 」パターンを使用します。次に、「<strong> products_02」</strong> パターンを使用して、「<strong> products_02</strong> 」インデックスの新しいデータ ビューを作成するプロセスを繰り返します。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blte826fd932cfeb9df/6a17fdffec0f8912aa5a6841/3ad4a6891a3905e96532a312932fdf3a8216aec2-1600x599.png" alt="" /><p>データ ビューを構成したら、分析 &gt; 検出に戻り、検証を開始できます。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltba3729c60068e8a0/6a17fe01e9ea87ba2aa9c82a/422c4b2b51abae6580cad25085d1b8a365fc6b9e-1294x850.png" alt="" /><p>ここで、DataView 製品を選択し、「タブレット」という用語で検索を実行すると、「Kindle Paperwhite」や「Apple iPad Air」などの製品があることがわかっているにもかかわらず、結果は表示されません。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt2c6a383dd4cb0157/6a17fe02577262671d1bce0c/e4ae3a785fdd93f48d7c7d204185ded149126f2c-1600x862.png" alt="" /><h4><code>products_02</code>インデックスで検索 (同義語をサポート)</h4><p>シノニムをサポートする「 <strong>products_synonyms</strong> 」データ ビューで同じクエリを実行すると、製品が正常に取得されました。これは、構成された同義語セットが正しく機能していることを示しており、検索された用語のさまざまなバリエーションが期待どおりの結果を返すことが保証されています。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt986b4706e2f70014/6a17fe043e9e454edbba16d3/e609749c39e90d5c82fa846af6124679dd62bcb8-1600x526.png" alt="" /><p>同じクエリを Kibana DevTools で直接実行することで、同じ結果を得ることができます。Elasticsearch Search API を使用して、products_02 インデックスを検索するだけです。</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltbe829a3c4d7aac60/6a17fe05e8fbce03d73a1bd7/504d0d1f96dcfbceb309063dc0716bcee64ad2f8-1600x870.png" alt="" /><h2>まとめ</h2><p>Elasticsearch に同義語を実装することで、製品カタログ検索の精度と範囲が向上しました。主な差別化要因は<strong>LLM</strong>の使用であり、これにより同義語が自動的かつ文脈に応じて生成され、事前定義されたリストの必要性がなくなりました。モデルは製品名とカテゴリを分析し、電子商取引に関連する同義語を確保しました。</p><p>さらに、<strong>同義語 API により</strong>辞書管理が簡素化され、同義語セットを動的に変更できるようになりました。このアプローチにより、検索はより柔軟になり、さまざまなユーザーのクエリ パターンに適応できるようになりました。</p><p>このプロセスは、新しいデータとモデルの調整によって継続的に改善され、ますます効率的な研究体験を保証します。</p><h2>参照資料</h2><p><strong>Elasticsearchをローカルで実行する</strong></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/run-elasticsearch-locally.html</a></p><p><strong>同義語API</strong></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/synonyms-apis.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/synonyms-apis.html</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-synonyms-automate</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-synonyms-automate</guid>
    <category><![CDATA[関連性]]></category>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt0f0247b9bc1d1ccd/6a17fe07ec0f891c745a6845/05a3cfeaa387561d5334ca3f1609035ddfff7481-1200x628.png" length="0" type="image/png"/>
    <pubDate>Thu, 27 Mar 2025 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[ログを活用して繁栄を：Elasticsearchの新しく特化したlogsdbインデックスモード]]></title>
    <description><![CDATA[Elasticsearch のログ管理における最新のイノベーションである logsdb は、ログ データのストレージ フットプリントを最大 65% 削減し、すべてのデータにアクセスして検索可能な状態を保ちながら、監視およびセキュリティ チームが予算を超過することなく可視性を拡張できるようにします。]]></description>
    <content:encoded><![CDATA[<h2>Elasticsearchの新しいインデックスモード、logsdbにより、ログストレージの必要量が最大65%削減</h2><p>本日、Elasticsearch の新しいインデックス モードである logsdb の一般提供開始を発表しました。これにより、logsdb のない Elasticsearch の最新バージョンと比較して<strong>、ログ データのストレージ フットプリントが最大 65% 削減されます</strong>。この劇的な改善により、観測性およびセキュリティ チームは、予算を超過することなく可視性を拡張しながら、すべてのデータを分析のためにすぐにアクセスできるようになります。</p><p>Logsdbはデータの順序を最適化し、<code>synthetic _source</code>で即座に非格納フィールド値を再構築することにより重複を排除します。また、高度なアルゴリズムとコーデックを使用して圧縮を改善するとともに、Elasticsearch内の列型ストレージを活用して、効率的なログのストレージと取得を実現します。</p><h2>logsdbインデックスモードを使用してストレージ効率を改善し、分析を強化し、コストを削減</h2><p>ログは、オブザーバビリティとセキュリティの問題を検出し修正するための重要なシグナルを提供します。AIの進歩によりテキストベースのデータの分析が容易になるにつれて、その有用性は増しており、効率的なストレージと高性能なアクセスがこれまで以上に重要になっています。</p><p>残念ながら、インフラストラクチャーやアプリケーションによって生成されるログ量の増加はコストを押し上げており、データ収集の制限、保存期間の短縮、最新データをサイロ化されたアーカイブ層に追いやったりといった、分析を妨げる妥協を強いられています。</p><p>Logsdbはこれらの課題に直接対処します。ストレージ効率が向上すれば、より多くのデータを収集でき、複雑なデータフィルタリングの手間を避けることができます。脅威ハンティング、インシデント対応、コンプライアンス要件をサポートするために、ログをより長く保持することができます。すべてのデータが常に検索可能であるため、データセットがどれほど大きくなっても、迅速に洞察を得ることができます。</p><h2>logsdbインデックスモードの背後にある技術的革新</h2><p>Logsdbインデックスモードは、スマートインデックスソート、synthetic _source、および高度な圧縮を使用して、ログデータのディスクフットプリントを劇的に削減します。これを実装することで、logsdbを使用しない最新バージョンのElasticsearchと比較して、ログストレージの必要量を最大65%削減できます。現在、logsdbはインデキシング時により多くのCPUを使用しますが、その効率的なストレージによって、ほとんどのお客様にとって全体的なコストが削減されます。長期的なデータ保持を必要とするお客様には、総所有コスト（TCO）が最大50%削減されることを見込んでいます。</p><p><strong>スマート インデックス ソート</strong>により、類似のデータを近くに配置することで、ストレージ効率が最大 30% 向上し、一部のログ データ セットでのクエリの待機時間が短縮されます。デフォルトでは、インデックスは host.name と @timestamp でソートされます。データにさらに適切なフィールドがある場合は、代わりにそれを指定することもできます。</p><p><strong>高度な圧縮</strong>により、Zstandard 圧縮 (Zstd)、デルタ エンコーディング、ランレングス エンコーディング、および自動的に選択されるその他のスマート コーデックを通じて、ログなどのテキストを多く含むデータのストレージ要件が大幅に削減されます。圧縮とパフォーマンスが最適化された列形式で保存される Doc-values により、並べ替え、集計、スクリプト用のフィールド値を効率的に保存および取得できます。</p><p><strong>合成 _source を</strong>使用すると、組織は _source フィールドを破棄し、オンデマンドでそれを完全にまたは部分的に再構築することで、ストレージのニーズをさらに 20 ～ 40% 削減できます。この機能では、インデックス作成と検索により多くの計算が必要になる場合もありますが、テストでは測定可能な純効率の向上がもたらされることが示されています。Synthetic _source は、ほぼ 2 年間のメトリクスを使用した本番環境での使用に基づいて構築されており、ほぼすべてのフィールド タイプのサポートを含む、ログの多数の機能強化が行われています。</p><p>結果として得られるストレージの節約は、インデックスライフサイクルの各フェーズに渡って反映されます。ホットティアでのストレージ削減が65％である場合、ウォーム、コールド、フローズンティアでも同様に65%の削減が適用され、スナップショットをバケットストレージに保存する際のフットプリントも削減されます。</p><h2>可視性を妥協しない：オブザーバビリティとセキュリティのためにすべてのログを保持</h2><p>ログはインフラストラクチャとアプリケーションの可視性の基盤であり、監視とトラブルシューティングのための最も単純で基本的なシグナルを提供します。しかし、ログの量の増加に伴い、コストが上昇しています。この課題により、お客様は複雑なフィルタリングおよび管理ポリシーを導入する必要に迫られたり、データを早期に削除したり、データを取り出して分析できる状態にするには1日以上かかるストレージに関連ログを格納することを余儀なくされています。完全で、簡単に検索でき、アクセス可能なデータセットがなければ、問題を見つけて解決することは大幅に困難になります。</p><p>Logsdb インデックス モードは<a href="https://www.elastic.co/jp/elasticsearch/elasticsearch-searchable-snapshots">、検索可能なスナップショット</a>や<a href="https://www.elastic.co/jp/blog/automatic-import-ai-data-integration-builder">自動インポート</a>などの画期的な Elasticsearch 機能を基盤として構築されており、運用チームとセキュリティ チームの次のような問題点に対処します。</p><p><strong>コストの削減:</strong> Logsdb はログのストレージ フットプリントを最大 65% 削減し、組織がより多くのデータを保持しながらストレージ費用を削減できるようにします。これにより、ホットからフローズンまですべてのストレージ層でコストが削減され、このデータを使用する観測性およびセキュリティ チームの生産性が向上します。</p><p><strong>貴重なデータを保存:</strong> Logsdb はすべてのログ データを保存し、追加のツールや複雑なフィルターに頼ることなく運用効率を向上させます。合成 _source などの機能を使用すると、ソース ドキュメント全体を保存せずにデータの値を保持できます。</p><p><strong>可視性の拡張:</strong> Logsdb は、観測性、セキュリティ、履歴データ用の個別のサイロなしで、1 つのプラットフォーム上のすべてのデータへの効率的なアクセスを提供します。サイト信頼性エンジニア (SRE) にとっては、メトリック、トレース、ビジネス データとともにログを分析できるため、問題解決が迅速化されます。同様に、セキュリティ オペレーション センター (SOC) チームにとっては、盲点を排除することで調査と修復が加速されます。</p><p><strong>データへのアクセスを合理化:</strong> Logsdb を使用すると、SRE チームはトラブルシューティング、傾向分析、分析のために実用的なデータを効率的に保持できます。同様に、SOC チームは、法外なコストをかけずに、調査や脅威ハンティングのためにすべてのデータを迅速に検索できます。</p><h2>Logsdbはあなたの環境に対応しています</h2><p>Elasticsearch logsdb インデックス モードは、バージョン 8.17 以降、Elastic Cloud Hosted および Self-Managed のお客様に一般提供され、 <a href="https://www.elastic.co/jp/elasticsearch/serverless">Elastic Cloud Serverless</a>のログではデフォルトで有効になっています。</p><p>基本的なlogsdbの機能（スマートインデックスソートや高度な圧縮を含む）は、Standard、Gold、Platinumライセンスをお持ちの組織で利用可能です。ストレージ要件をさらに削減する完全なlogsdb機能（synthetic _sourceを含む）は、サーバーレスのお客様およびエンタープライズライセンスをお持ちの組織で利用可能です。</p><h2>Elasticsearch logsdb の動作</h2><p>Logsdbを使用すると、データの収集範囲を狭めたり、データを破棄したりサイロ化したりすることなく、すべてのログデータを保持し、運用効率を向上させることができます。スマートインデックスソート、高度な圧縮、synthetic _sourceなどの機能を活用して、必要なデータを予算内で保持し、分析することができます。</p><p>自分で体験してみませんか？<a href="https://cloud.elastic.co/registration">Elastic を無料でお試しください</a>。</p><p><em>本記事に記述されているあらゆる機能ないし性能のリリースおよびタイミングは、Elasticの単独裁量に委ねられます。現時点で提供されていないあらゆる機能ないし性能は、すみやかに提供されない可能性、または一切の提供が行われない可能性があります。</em></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/elasticsearch-logsdb-index-mode</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/elasticsearch-logsdb-index-mode</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Mark Settle,George Kobar,Amena Siddiqi]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt982a3c761d66169f/6a17de7c7b54f9788d8b37ff/d3daacafea7a1d78c825a18f8281460c7106d3a5-721x420.png" length="0" type="image/png"/>
    <pubDate>Thu, 12 Dec 2024 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[セマンティック検索の実装: Elasticsearch を使ったレシピ検索の構築]]></title>
    <description><![CDATA[電子商取引 Web サイトのコンテキストでセマンティック検索を実装します。]]></description>
    <content:encoded><![CDATA[<h2>はじめに</h2><p>多くの電子商取引ウェブサイトは、レシピ検索エクスペリエンスを強化することに関心を持っています。セマンティック検索を正しく適用すると、顧客は「バレンタインデー用の何か」や「感謝祭の食事」など、より自然なクエリに基づいて必要な材料をすばやく見つけることができます。</p><p>この記事では、Elasticsearch を使用して、このようなクエリをサポートするセマンティック検索を実装する方法を説明します。スーパーマーケットの食材や製品のカタログを保存するためのインデックスを設定し、このインデックスを使用してレシピ検索を改善する方法を説明します。この記事全体を通して、このデータ構造を作成し、自然言語処理技術を適用して顧客の意図に沿った関連性の高い結果を提供する方法について説明します。</p><p>この記事で紹介したコードはすべて Python で開発されており、 <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/building-a-recipe-search-with-elasticsearch">GitHub</a>で入手できます。リポジトリにアクセスしてソース コードを確認し、必要に応じて調整し、開発環境に直接ソリューションを実装できます。</p><h2>セマンティック検索の実装を開始</h2><p>セマンティック検索の実装を開始するには、まず自然言語モデルを定義する必要があります。Elastic は独自のモデル<a href="https://www.elastic.co/guide/en/machine-learning/8.15/ml-nlp-elser.html"><strong>ELSER</strong></a>を提供していますが、Hugging Face など、さまざまなプロバイダーの NLP モデルの統合もサポートしています。この柔軟性により、ニーズに最適なオプションを選択できます。</p><p>この記事では、NLP モデルの展開と管理の複雑さを軽減する<strong>ELSER</strong>を使用します。さらに、Elastic は<a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html"><strong>semantic_text</strong></a>機能を提供しており、これによりプロセスが大幅に簡素化されます。<strong>semantic_text</strong>を使用すると、埋め込み生成プロセス全体が簡単かつ自動化されます。推論ポイントを定義し、インデックス マッピングで埋め込みを受け取るフィールドを指定するだけです。ドキュメントのインデックス作成中に埋め込みが生成され、指定されたフィールドに自動的に関連付けられます。</p><h3>セットアップ手順</h3><p>以下は、セマンティック検索をサポートするインデックスを作成する手順です。以下の手順に従うと、インデックスが設定され、セマンティック検索の準備が整います。</p><ol><li><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html"><strong>推論ポイント を作成します</strong></a> 。</p></li><li><p><a href="https://github.com/andreluiz1987/semantic-search-market/blob/main/infra.py"><strong>インデックスを作成し</strong></a>、埋め込みを受け取ることができるように説明フィールドを semantic_text として設定します。</p></li><li><p>製品カタログを保存する食料品カタログ インデックスに<a href="https://github.com/andreluiz1987/semantic-search-market/blob/main/ingestion.py"><strong>データをインデックスします</strong></a>。このカタログは、<a href="https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv">ここに</a>あるデータセットから取得されました。</p></li></ol><h2>スーパーマーケットにおけるセマンティック検索の応用</h2><p>食料品店の製品データがインデックスに入力されたので、セマンティック検索を使用して検索結果を改善するためのクエリをテストおよび検証しています。私たちの目標は、コンテキストとユーザーの意図を理解し、より関連性の高い正確な結果を提供する、よりスマートな検索エクスペリエンスを提供することです。</p><h3>セマンティック検索が解決する課題</h3><p>製品カタログに基づいて、従来の語彙検索ではしばしば問題となる語彙とコンテキストの問題に対処することで、セマンティック検索が食料品店での検索エクスペリエンスをどのように変革できるかを探ってみましょう。</p><h4><strong>1. 料理の意図の解釈</strong></h4><p><strong>問題 01</strong> : 顧客が「グリル用シーフード」を検索する場合、語彙検索システムはクエリの背後にある意図を完全に理解できない可能性があります。グリルに適したシーフード製品をすべて識別できず、製品名に「シーフード」または「グリル」という正確な用語が含まれる製品のみが返される可能性があります。</p><p>まず、語彙検索を実行し、結果を分析します。次に、セマンティック検索で同じことを実行し、同じ検索語の結果を比較します。</p><p><strong>クエリ語彙検索</strong></p> response = client.search(
        index="grocery-catalog",
        size=5,
        source_excludes="description_embedding",
        query={
            "multi_match": {
                "query": "seafood for grilling",
                "fields": [
                    "name",
                    "description"]
            }
        }
    )<p><strong>結果：</strong></p><p>検索タイプ</p><p>名前</p><p>スコア</p><p>語彙</p><p>北西部の魚 アラスカ産ベアディズワイガニ</p><p>10.453125</p><p>語彙</p><p>吉田さんのソース オリジナルグルメ</p><p>7.2289705</p><p>語彙</p><p>プレミアムシーフードバラエティパック - 20個</p><p>7.1924105</p><p>語彙</p><p>アメリカ産レッドスナッパー - 丸ごと、頭付き、洗浄済み</p><p>6.998647</p><p>語彙</p><p>ロブスターの爪と腕、持続可能な天然漁獲</p><p>6.438654</p><p>語彙検索により、American Red Snapper や Northwest Fish Alaskan Bairdi Snow Crab など、グリルに適した魚介類がいくつか返されました。しかし、語彙検索では、シーフードではなくミートソースであるミスターヨシダソースなど、関連性の低い商品がリストの上位に表示され、語彙アルゴリズムが「グリル用」の文脈を完全に理解するのに苦労していることが示唆されました。</p><p><strong>セマンティック検索ソリューション</strong></p><p>「シーフード」という用語と「グリル」などの調理コンテキストを組み合わせたクエリを使用して、商品名に「グリル」や「シーフード」という単語が直接表示されていない場合でも、グリルに最適な魚の切り身、エビ、ホタテなどの包括的なオプションのリストを返します。これにより、検索結果が顧客の意図にさらに一致するようになります。</p><p><strong>クエリセマンティック検索:</strong></p>es_client.search(
   index="grocery-catalog-elser",
   size=size,
   source_excludes="description_embedding",
   query={
       "semantic": {
           "field": "description_embedding",
           "query": "seafood for grilling"

       }
   })<p>検索タイプ</p><p>名前</p><p>スコア</p><p>セマンティック</p><p>頭付き、スズキの丸ごと一匹</p><p>16.175909</p><p>セマンティック</p><p>アラスカ産クロタラ（セーブルフィッシュ）</p><p>15.855331</p><p>セマンティック</p><p>アメリカ産レッドスナッパー - 丸ごと、頭付き</p><p>15.454779</p><p>セマンティック</p><p>北西部の魚 アラスカ産ベアディズワイガニ</p><p>15.855331</p><p>セマンティック</p><p>アメリカ産レッドスナッパー - 丸ごと、頭付き</p><p>15.3892355</p><p>セマンティック検索では、「シーフード」という用語に直接関連する製品が返されるだけでなく、「グリル」というコンテキストも理解し、グリルに適した丸ごとの魚や切り身も表示されました。ここで重要なのは結果の精度であり、これにはグリル料理によく使われるスズキやアラスカ産黒タラなどの丸ごとの魚のオプションも含まれていました。</p><p><strong>問題 02</strong> : 多くの顧客は、仕事で長い一日を過ごした後、「平日の簡単な食事」などの用語を使用して、手早く簡単に作れる夕食の解決策を検索します。従来の語彙検索では、手軽な食事という概念を完全には捉えることができず、多くの場合、名前に「簡単」という言葉が含まれる商品のみに焦点が当てられます。</p><p>前の問題と同様に、まずは語彙検索を実行します。その後、セマンティック検索を使用したソリューションを適用します。</p><p><strong>クエリ語彙検索</strong></p> response = client.search(
        index="grocery-catalog",
        size=5,   
        source_excludes="description_embedding",
        query={
            "multi_match": {
                "query": "easy weeknight meals",
                "fields": [
                    "name",
                    "description"]
            }
        }
    )<p><strong>結果：</strong></p><p>検索タイプ</p><p>名前</p><p>スコア</p><p>語彙</p><p>Avery イージーピール 住所ラベル 4200枚</p><p>8.017723</p><p>語彙</p><p>Omeals 自己加熱式非常食/携帯食 32</p><p>6.592727</p><p>語彙</p><p>沿岸シーフード キハダマグロの角切りポケ</p><p>5.836883</p><p>語彙</p><p>重量感のある超重量12オンスフォーム</p><p>5.8116536</p><p>語彙</p><p>ヴァニティフェア エブリデイ ナプキン 2枚重ね 110枚入り</p><p>5.752989</p><p>語彙検索では、Avery Easy Peel Address Labels や Vanity Fair Everyday Napkins など、食事とはまったく関係のないアイテムも含め、関連性の低い結果が返されました。これらの製品は、手早く食事をしたいというユーザーのニーズを満たしていません。語彙検索では確かに 1 つの便利な製品 (Omeals Self Heating Emergency Meals) が返されましたが、ナプキンやラベルなどの他の結果は説明にある「簡単」または「平日の夜」という単語に一致するだけで、素早い食事の解決策を求めるユーザーの意図に真に応えるものではありませんでした。</p><p><strong>セマンティック検索ソリューション</strong></p><p>手早く簡単に食べられる食事の意図を理解するクエリを実装しました。これは、名前に「簡単」という言葉が明示的に含まれていなくても、調理済みの肉、冷凍パスタ、ミールキットなど、すぐに準備できる製品を関連付けます。このアプローチにより、顧客は平日の夜に素早く夕食をとるのに最適なオプションを見つけられるようになり、利便性のニーズに応えます。</p><p><strong>クエリセマンティック検索</strong></p>es_client.search(
   index="grocery-catalog-elser",
   size=size,
   source_excludes="description_embedding",
   query={
       "semantic": {
           "field": "description_embedding",
           "query": "easy weeknight meals"

       }
   })<p><strong>結果：</strong></p><p>検索タイプ</p><p>名前</p><p>スコア</p><p>セマンティック</p><p>Omeals 自己加熱式非常食/携帯食 32</p><p>14.610006</p><p>セマンティック</p><p>日清カップヌードル、エビ、2.5オンス</p><p>13.751424</p><p>セマンティック</p><p>ナマステ グルテンフリー ワッフル＆パンケーキミックス</p><p>13.73376</p><p>セマンティック</p><p>アイダホポテト、ゴールデングリルハッシュブラウンポテト</p><p>12.549422</p><p>セマンティック</p><p>日清 カップヌードル チキン 24個入り</p><p>12.034527</p><p>セマンティック検索では、インスタントラーメン（カップヌードル）、調理済みのジャガイモ、パンケーキミックスなど、平日の夜に簡単に作れる夕食の典型的な選択肢である、手軽で便利な食事に明確に関連する製品が返されました。これは、セマンティック検索が「平日の夜に簡単に作れる食事」というフレーズの背後にある概念を理解し、手早く簡単に作れる食事を見つけたいというユーザーの意図を捉えることができることを示しています。興味深いことに、「ソーダ」などの他のカテゴリの製品も、コンテキストに関連がある場合（食事に添える飲み物など）に含まれることがあります。</p><h4><strong>2. 地域用語と語彙のバリエーション</strong></h4><p><strong>問題</strong>: ある顧客が「ソーダ」を検索する一方で、別の顧客は同じ商品を「ポップ」で検索する可能性があります。従来の語彙検索では、両方の用語が同じ項目を指していることを認識できません。</p><p><strong>クエリ語彙検索</strong></p> response = client.search(
        index="grocery-catalog",
        size=5,
        source_excludes="description_embedding",
        query={
            "multi_match": {
                "query": "refreshing pop drink low sugar",
                "fields": [
                    "name",
                    "description"]
            }
        }
    )<p><strong>結果：</strong></p><p>検索タイプ</p><p>名前</p><p>スコア</p><p>語彙</p><p>プライムハイドレーション+スティック 電解質ドリンクミックス</p><p>14.492869</p><p>語彙</p><p>カプリサン、100%ジュース、バラエティパック</p><p>12.340851</p><p>語彙</p><p>ジョイバースト エナジードリンク、フローズンローズ、12</p><p>11.839179</p><p>語彙</p><p>ケロッグのポップタルト、フロステッドブラウンシュガーシナモン</p><p>9.97788</p><p>語彙</p><p>カインド ミニバー バラエティパック 0.7</p><p>9.336912</p><p>語彙検索は、正確な単語の一致に焦点を当てます。Prime Hydration や Capri Sun などの製品が返される一方で、「pop」という用語との直接一致により、飲み物ではなくスナックである Kellogg's Pop-Tarts など、無関係な結果も表示されました。これは、用語に複数の意味がある場合やあいまいな場合、語彙検索の効果が低下する可能性があることを浮き彫りにしています。</p><p><strong>セマンティック検索ソリューション</strong></p><p>セマンティッククエリでは、語彙検索では解決できない語彙のバリエーションの問題を克服できます。検索用語を拡張することで、文脈上の意味に基づいた結果を得ることができ、より関連性の高い包括的な回答を提供できます。</p><p><strong>クエリ:</strong></p>es_client.search(
   index="grocery-catalog-elser",
   size=size,
   source_excludes="description_embedding",
   query={
       "semantic": {
           "field": "description_embedding",
           "query": "refreshing pop drink low sugar"

       }
   })<p><strong>結果：</strong></p><p>検索タイプ</p><p>名前</p><p>スコア</p><p>セマンティック</p><p>オリポップ 12オンス プレバイオティクスソーダ バラエティ</p><p>14.776867</p><p>セマンティック</p><p>バイ アンチオキシダント ココフュージョン バラエティパック 18個</p><p>14.663253</p><p>セマンティック</p><p>モンスターエナジードリンク、ゼロウルトラ、24</p><p>14.486348</p><p>セマンティック</p><p>ジョイバースト エナジー バラエティ、12液量オンス</p><p>14.007214</p><p>セマンティック</p><p>ジョイバースト エナジードリンク、フローズンローズ、12</p><p>13.641038</p><p>セマンティック検索では、製品名に「pop」という正確な用語が含まれていない場合でも、「soda」の同義語として「pop」の概念に直接一致する製品 (Olipop Prebiotics Soda など) が返されます。検索では、ユーザーの意図（爽やかな低糖飲料）を理解し、プレバイオティクスソーダ（Olipop）や無糖エナジードリンク（Monster Energy Drink）などのオプションを含む関連商品を返すことができました。</p><h2>まとめ</h2><p>食料品店のコンテキストでセマンティック検索を実装すると、「グリル用の魚介類」や「平日の簡単な食事」などの複雑なクエリを理解するのに非常に効果的であることが証明されています。このアプローチにより、ユーザーの意図をより正確に解釈し、関連性の高い商品を返すことができました。</p><p>Elasticsearch を使用し、ELSER でプロセスを簡素化することで、セマンティック検索を迅速かつ効率的に適用し、検索結果を大幅に改善し、より機敏でターゲットを絞ったショッピング体験を提供できるようになりました。これにより、検索プロセスが最適化されるだけでなく、顧客に提供される結果の関連性も高まりました。</p><h2>参照資料</h2><p>モデル ELSER:</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/put-inference-api.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/put-inference-api.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/infer-service-elser.html</a></p><p></p><p>意味テキスト:</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-text.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-text.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html</a></p><p></p><p>データセット:</p><p><a href="https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv">https://www.kaggle.com/datasets/bhavikjikadara/grocery-store-dataset?select=GroceryDataset.csv</a></p><p></p><p>セマンティック検索:</p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search.html</a></p><p><a href="https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html">https://www.elastic.co/guide/en/elasticsearch/reference/current/semantic-search-semantic-text.html</a></p>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/semantic-search-elasticsearch-ecommerce</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/semantic-search-elasticsearch-ecommerce</guid>
    <category><![CDATA[基本]]></category>
    <dc:creator><![CDATA[Andre Luiz]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt5c545fc80b6d79d6/6a170214839dfad776dcfd6f/d968e646240cd3ef7c79b5124d562a5f951d812b-1440x840.png" length="0" type="image/png"/>
    <pubDate>Thu, 07 Nov 2024 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>