OpenSearch Serverlessでベクトル検索・キーワード検索を試してみた

# 背景・目的
前回、ベクトル検索について整理しました。今回はOpenSearch Service Serverlessを使用して試してみます。

https://qiita.com/zumax/items/88cbfebcad0041c0799a

# まとめ
下記に特徴を整理します。

|特徴|説明|
|:--|:--|
|settings|インデックスの設定（KNN検索を有効にするなど）<BR>index.knn:trueは、KNN検索を有効にしている|
|mappings|フィールドの定義（型やベクトルの次元など）<BR>文章のタイトルなどを保存するフィールド。全文検索（フリーワード検索）に対応している<BR>text型は、検索時にトークンに分割されて検索可能になる
|embedding|ベクトル検索用のフィールド|



# 概要
## CloudFormation
CloudFormationで、OpneSearch Service Serverlessを作成します。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/AWS_OpenSearchServerless.html


### Collection
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-opensearchserverless-collection.html

```yml
Type: AWS::OpenSearchServerless::Collection
Properties:
  Description: String
  Name: String
  StandbyReplicas: String
  Tags: 
    - Tag
  Type: String
```

- StandbyReplicas
    - レプリカを用意するか？今回は検証なのでDISALBLEにします
- Type
    - コレクションのタイプ
    - 下記から選びます
        - SEARCH
        - TIMESERIES
        - VECTORSEARCH


### SecurityPolicy
networkとencryptionの2つがある


https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-opensearchserverless-securitypolicy.html#cfn-opensearchserverless-securitypolicy-policy

```yml
Type: AWS::OpenSearchServerless::SecurityPolicy
Properties:
  Description: String
  Name: String
  Policy: String
  Type: String
```
- Type
    - セキュリティ ポリシーのタイプ
    - 下記から選びます
        - encryption
        - network
- Policy
    - Typeに応じた内容を書きます

#### encryption
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-opensearchserverless-securitypolicy.html#aws-resource-opensearchserverless-securitypolicy--examples--Create_an_encryption_policy


```yml
Description: OpenSearch Serverless encryption policy template
Resources:
  TestSecurityPolicy:
    Type: 'AWS::OpenSearchServerless::SecurityPolicy'
    Properties:
      Name: logs-encryption-policy
      Type: encryption
      Description: Encryption policy for test collections
      Policy: >-
        {"Rules":[{"ResourceType":"collection","Resource":["collection/logs*"]}],"AWSOwnedKey":true}
```

- AWSOwnedKey:trueの場合、AWS所有のKMSキーを使う

#### network
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-opensearchserverless-securitypolicy.html#aws-resource-opensearchserverless-securitypolicy--examples--Create_a_network_policy

```yml
Description: OpenSearch Serverless network policy template
Resources:
  SecurityPolicy:
    Type: 'AWS::OpenSearchServerless::SecurityPolicy'
    Properties:
      Name: logs-network-policy
      Type: network
      Description: Network policy for test collections
      Policy >-
        [{"Rules":[{"ResourceType":"collection","Resource":["collection/logs*"]},
        {"ResourceType":"dashboard","Resource":["collection/logs*"]}],"AllowFromPublic":true}]
```

- AllowFromPublic:Public アクセス可能。falseの場合にVPCアクセスのみとなるため、SourceVPCeを指定する

### AccessPolicy
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-resource-opensearchserverless-accesspolicy.html

```yml
Type: AWS::OpenSearchServerless::AccessPolicy
Properties:
  Description: String
  Name: String
  Policy: String
  Type: String
```

- Typeにはdataを指定


# 実践

## 前提
### 環境
OS:MacOS
エディタ:Cursor
言語：Python

### IAMロール
https://qiita.com/zumax/items/d6553d5521db1537702f#%E5%AE%9F%E8%B7%B5

下記のIAMポリシーをSSOアカウントのインラインポリシーに設定しておきます
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "aoss:CreateCollection",
        "aoss:ListCollections",
        "aoss:BatchGetCollection",
        "aoss:DeleteCollection",
        "aoss:CreateAccessPolicy",
        "aoss:ListAccessPolicies",
        "aoss:UpdateAccessPolicy",
        "aoss:CreateSecurityPolicy",
        "aoss:GetSecurityPolicy",
        "aoss:UpdateSecurityPolicy",
        "iam:ListUsers",
        "iam:ListRoles"
      ],
      "Effect": "Allow",
      "Resource": "*"
    }
  ]
}
```

## 事前準備

1. リポジトリを作成します
    ```bash
    % gh repo create opensearch-test --public --clone
    ✓ Created repository XXXXX/opensearch-test on GitHub
      https://github.com/XXXXX/opensearch-test
    %
    % gh repo view XXXXX/opensearch-test          

    XXXXX/opensearch-test
    No description provided

    This repository does not have a README

    View this repository on GitHub: https://github.com/XXXXX/opensearch-test
    % 
    ```
1. フォルダをワークスペースに追加で、作成したフォルダを指定します


## CloudFormation テンプレートで OpenSearch Serverlessを作成
1. templatesフォルダを作成します
1. templates/opensearch-serveless.ymlを作成し、下記のコードを書きます
    ```yml
    AWSTemplateFormatVersion: '2010-09-09'
    Description: 'AWS OpenSearch Serverless Deployment Template'
    
    
    Parameters:
      DataAccessPrincipal:
        Type: String
    
    
    Resources:
      VectorSearchCollection:
        Type: AWS::OpenSearchServerless::Collection
        Properties:
          Name: vector-search-collection
          Description: 'OpenSearch Serverless collection for vector search'
          StandbyReplicas: DISABLED
          Type: VECTORSEARCH
        DependsOn:
          - EncryptionPolicy
          - NetworkPolicy
    
      EncryptionPolicy:
        Type: AWS::OpenSearchServerless::SecurityPolicy
        Properties:
          Name: encryption-policy
          Description: 'Encryption policy for OpenSearch Serverless'
          Type: encryption
          Policy: >-
            {
              "Rules": [
                {
                  "ResourceType": "collection",
                  "Resource": ["collection/vector-search-collection"]
                }
              ],
              "AWSOwnedKey": true
            }
      NetworkPolicy:
        Type: AWS::OpenSearchServerless::SecurityPolicy
        Properties:
          Name: network-policy
          Description: 'Network policy for OpenSearch Serverless'
          Type: network
          Policy: >-
            [
              {
                "Rules": [
                  {
                    "ResourceType": "collection",
                    "Resource": ["collection/vector-search-collection"]
                  },
                  {
                    "ResourceType": "dashboard",
                    "Resource": ["collection/vector-search-collection"]
                  }
                ],
                "AllowFromPublic": true
              }
            ]
    
      # ベクター検索用アクセスポリシー
      VectorSearchAccessPolicy:
        Type: AWS::OpenSearchServerless::AccessPolicy
        Properties:
          Name: vector-search-access-policy
          Description: 'Access policy for vector search collection'
          Type: data
          Policy: !Sub >-
            [
              {
                "Description": "Access for cfn user",
                "Rules": [
                  {
                    "ResourceType": "index",
                    "Resource": ["index/*/*"],
                    "Permission": ["aoss:*"]
                  },
                  {
                    "ResourceType": "collection",
                    "Resource": ["collection/vector-search-collection"],
                    "Permission": ["aoss:*"]
                  }
                ],
                "Principal": ["${DataAccessPrincipal}"]
              }
            ]
        DependsOn:
          - VectorSearchCollection

    ```

## makeファイルを作成
1. プロジェクト直下に Makefileを作成し、下記のコードを書きます
    ```makefile
    .PHONY: deploy validate destroy
    
    # AWS profile and region settings
    AWS_PROFILE ?= default
    AWS_REGION ?= ap-northeast-1
    STACK_NAME ?= opensearch-serverless-stack
    DATA_ACCESS_PRINCIPAL ?= $(shell aws sts get-caller-identity --query 'Account' --output text --profile $(AWS_PROFILE) --region $(AWS_REGION))
    
    # CloudFormation template path
    TEMPLATE_FILE = templates/opensearch-serveless.yml
    
    validate:
    	@echo "Validating CloudFormation template..."
    	aws cloudformation validate-template \
    		--template-body file://$(TEMPLATE_FILE) \
    		--profile $(AWS_PROFILE) \
    		--region $(AWS_REGION)
    
    deploy:
    	@echo "Deploying OpenSearch Serverless stack..."
    	@echo "Using DataAccessPrincipal: $(DATA_ACCESS_PRINCIPAL)"
    	aws cloudformation deploy \
    		--template-file $(TEMPLATE_FILE) \
    		--stack-name $(STACK_NAME) \
    		--capabilities CAPABILITY_IAM \
    		--profile $(AWS_PROFILE) \
    		--region $(AWS_REGION) \
    		--parameter-overrides DataAccessPrincipal=$(DATA_ACCESS_PRINCIPAL)
    
    destroy:
    	@echo "Destroying OpenSearch Serverless stack..."
    	aws cloudformation delete-stack \
    		--stack-name $(STACK_NAME) \
    		--profile $(AWS_PROFILE) \
    		--region $(AWS_REGION)
    
    help:
    	@echo "Available commands:"
    	@echo "  make validate  - Validate the CloudFormation template"
    	@echo "  make deploy    - Deploy the OpenSearch Serverless stack"
    	@echo "  make destroy   - Delete the OpenSearch Serverless stack"
    	@echo "  make help      - Show this help message"
    	@echo ""
    	@echo "Environment variables:"
    	@echo "  AWS_PROFILE   - AWS profile to use (default: default)"
    	@echo "  AWS_REGION    - AWS region to deploy to (default: ap-northeast-1)"
    	@echo "  STACK_NAME    - CloudFormation stack name (default: opensearch-serverless-stack)"
    	@echo "  DATA_ACCESS_PRINCIPAL - AWS account ID (default: current account)" 
    ```

## リソースの作成
1. 下記のコマンドを実行します
    ```bash
    % make deploy DATA_ACCESS_PRINCIPAL=arn:aws:iam::XXXXX:role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_XXXXX
    Deploying OpenSearch Serverless stack...
    Using DataAccessPrincipal: arn:aws:iam::XXXXX:role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_XXXXX
    aws cloudformation deploy \
                    --template-file templates/opensearch-serveless.yml \
                    --stack-name opensearch-serverless-stack \
                    --capabilities CAPABILITY_IAM \
                    --profile XXXXX \
                    --region ap-northeast-1 \
                    --parameter-overrides DataAccessPrincipal=arn:aws:iam::XXXXX:role/aws-reserved/sso.amazonaws.com/ap-northeast-1/AWSReservedSSO_XXXXX
    
    Waiting for changeset to be created..
    Waiting for stack create/update to complete
    Successfully created/updated stack - opensearch-serverless-stack
    %
    ```

1. できました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/f177925d-ca97-47f6-a5b2-7508becd787e.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/1ce37981-2e30-4ea4-aaae-dfca19b30c51.png)

## データの登録〜検索
OpneSearchのDev toolsから操作します

1. OpenSearch Serverlessに移動
1. ダッシュボードから作成したCollectionをクリックします
1. OpenSearch ダッシュボードをクリックします
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/fa8c3780-7fe4-44fa-b05d-258f2cdf74f9.png)

1. 「Dev Tools」をクリックします
    <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/2d95bf3e-52d2-4305-90cf-a7df4b1594fa.png" width=250 />


### ベクトル検索用インデックスの作成
1. 下記を貼り付けて実行します
    ```json
    PUT my-vector-index
    {
      "settings": {
        "index.knn": true
      },
      "mappings": {
        "properties": {
          "title": {
            "type": "text"
          },
          "description": {
            "type": "text"
          },
          "embedding": {
            "type": "knn_vector",
            "dimension": 4,
            "method": {
              "name": "hnsw",
              "space_type": "l2",
              "engine": "faiss"
            }
          }
        }
      }
    }
    ```

    - `PUT my-vector-index` は、my-vector-index というインデックス名
    - `settings`は、インデックスの設定（KNN検索を有効にするなど）
        - index.knn:trueは、KNN検索を有効にしている
    - `mappings`は、フィールドの定義（型やベクトルの次元など）
        - 文章のタイトルなどを保存するフィールド。全文検索（フリーワード検索）に対応している
        - text型は、検索時にトークンに分割されて検索可能になる
        - embedding
            - type : knn_vector
                - ベクトル検索専用
            - dimension: 4
                - このベクトルは4次元
                - 登録するデータも同じ長さにする必要がある
            - method
                - ベクトル検索のアルゴリズム設定
                - name:hnsw
                    - HNSW（Hierarchical Navigable Small World）
                - space_type
                    - l2、L2ノルム
                - engine:faiss
                    - Facebooks製ベクトル検索エンジン
    - これにより、タイトルのキーワード検索
    - ベクトルによる意味の近さ

1. 結果が返されました。acknowledgedがtrueで返されました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/8ba75dfa-832c-4a93-abfb-159ea2644820.png)
    ```json
    {
      "acknowledged": true,
      "shards_acknowledged": true,
      "index": "my-vector-index"
    }
    ```
1. インデックスもできました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/7c71af5d-6f52-4ab2-a2dc-e568e52fb384.png)

### データ登録
1. Dev Toolsでデータを登録します（最初の数件を表示していますが100件登録しました）
    ```json
    POST _bulk
    {"index": {"_index": "my-vector-index"}}
    {"title": "Distributed Systems in Action", "description": "Distributed Systems in Action - A comprehensive and practical book in the field of software and technology.", "embedding": [0.1038, 0.0859, 0.0608, 0.9006]}
    {"index": {"_index": "my-vector-index"}}
    {"title": "Java Cookbook", "description": "Java Cookbook - A comprehensive and practical book in the field of software and technology.", "embedding": [0.0535, 0.1386, 0.0729, 0.9075]}
    ・・・
    ```

1. 成功しました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/319eb3ab-7c64-4bfc-8157-d2a6b418ea71.png)

    ```json
    {
      "took": 330,
      "errors": false,
      "items": [
        {
          "index": {
            "_index": "my-vector-index",
            "_id": "1%3A0%3ABcLMCZYBtRq-o6tNRFQB",
            "_version": 1,
            "result": "created",
            "_shards": {
              "total": 0,
              "successful": 0,
              "failed": 0
            },
            "_seq_no": 0,
            "_primary_term": 0,
            "status": 201
          }
        },
        {
          "index": {
            "_index": "my-vector-index",
            "_id": "1%3A0%3ABsLMCZYBtRq-o6tNRFQB",
            "_version": 1,
            "result": "created",
            "_shards": {
              "total": 0,
              "successful": 0,
              "failed": 0
            },
            "_seq_no": 0,
            "_primary_term": 0,
            "status": 201
          }
        },
        ・・・・
    ```

1. ドキュメントの件数を確認します
    ```json
    GET my-vector-index/_search
    {
      "size": 0
    }
    ```
1. 104件返されました。（何回か手動で実行したので、100件ではなく104件になっています）
    ```json
    {
      "took": 17,
      "timed_out": false,
      "_shards": {
        "total": 0,
        "successful": 0,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": {
          "value": 104,
          "relation": "eq"
        },
        "max_score": null,
        "hits": []
      }
    }
    ```

1. マネコンでも確認できました
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/206276/6c3ffc35-b6b4-458b-a687-cc5e5b6cab89.png)



### KW検索（match）
titleに「Python」を含む本を検索します


1. 下記のコマンドを実行します
    ```json
    GET my-vector-index/_search
    {
      "query": {
        "match": {
          "title": "Python"
        }
      }
    }
    ```

1. 下記の結果が返されました
    ```json
    {
      "took": 35,
      "timed_out": false,
      "_shards": {
        "total": 0,
        "successful": 0,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": {
          "value": 5,
          "relation": "eq"
        },
        "max_score": 3.6306305,
        "hits": [
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AUsLMCZYBtRq-o6tNRFQE",
            "_score": 3.6306305,
            "_source": {
              "title": "Python Essentials",
              "description": "Python Essentials - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.1098,
                0.0933,
                0.0612,
                0.8775
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AE8LMCZYBtRq-o6tNRFQC",
            "_score": 3.207633,
            "_source": {
              "title": "Python Handbook",
              "description": "Python Handbook - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0945,
                0.0828,
                0.0987,
                0.8597
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AWcLMCZYBtRq-o6tNRFQF",
            "_score": 3.207633,
            "_source": {
              "title": "Python Guide",
              "description": "Python Guide - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.1017,
                0.0959,
                0.1301,
                0.9075
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AIcLMCZYBtRq-o6tNRFQC",
            "_score": 3.160477,
            "_source": {
              "title": "Python for Professionals",
              "description": "Python for Professionals - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.1142,
                0.0918,
                0.0605,
                0.9455
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AL8LMCZYBtRq-o6tNRFQD",
            "_score": 2.2064066,
            "_source": {
              "title": "Python From Zero to Hero",
              "description": "Python From Zero to Hero - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0737,
                0.0824,
                0.0896,
                0.9137
              ]
            }
          }
        ]
      }
    }
    ```

### フレーズ検索（match_phrase）
説明文に完全に一致するフレーズを含む本を探します

1. 下記のコマンドを実行します
    ```json
    GET my-vector-index/_search
    {
      "query": {
        "match_phrase": {
          "description": "comprehensive and practical"
        }
      }
    }
    ```

1. 下記の結果が返されました
    ```json
    {
      "took": 38,
      "timed_out": false,
      "_shards": {
        "total": 0,
        "successful": 0,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": {
          "value": 104,
          "relation": "eq"
        },
        "max_score": 0.029437244,
        "hits": [
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3ABMLJCZYBtRq-o6tN-VS_",
            "_score": 0.029437244,
            "_source": {
              "title": "Java Cookbook",
              "description": "Java Cookbook - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0535,
                0.1386,
                0.0729,
                0.9075
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3ABsLMCZYBtRq-o6tNRFQB",
            "_score": 0.029437244,
            "_source": {
              "title": "Java Cookbook",
              "description": "Java Cookbook - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0535,
                0.1386,
                0.0729,
                0.9075
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AGsLMCZYBtRq-o6tNRFQC",
            "_score": 0.029437244,
            "_source": {
              "title": "Algorithms Practices",
              "description": "Algorithms Practices - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0501,
                0.0905,
                0.0558,
                0.9357
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AIsLMCZYBtRq-o6tNRFQC",
            "_score": 0.029437244,
            "_source": {
              "title": "DevOps Handbook",
              "description": "DevOps Handbook - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0669,
                0.0532,
                0.1023,
                0.8631
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3ANcLMCZYBtRq-o6tNRFQD",
            "_score": 0.029437244,
            "_source": {
              "title": "Microservices Handbook",
              "description": "Microservices Handbook - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.1049,
                0.0722,
                0.0817,
                0.8607
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AP8LMCZYBtRq-o6tNRFQD",
            "_score": 0.029437244,
            "_source": {
              "title": "Kubernetes Practices",
              "description": "Kubernetes Practices - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0568,
                0.0639,
                0.1313,
                0.9223
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AQ8LMCZYBtRq-o6tNRFQE",
            "_score": 0.029437244,
            "_source": {
              "title": "Kubernetes Guide",
              "description": "Kubernetes Guide - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.12,
                0.1067,
                0.1307,
                0.9149
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AT8LMCZYBtRq-o6tNRFQE",
            "_score": 0.029437244,
            "_source": {
              "title": "Rust Principles",
              "description": "Rust Principles - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0849,
                0.1196,
                0.1029,
                0.8612
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AUcLMCZYBtRq-o6tNRFQE",
            "_score": 0.029437244,
            "_source": {
              "title": "Databases Essentials",
              "description": "Databases Essentials - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0975,
                0.0597,
                0.0758,
                0.8662
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AUsLMCZYBtRq-o6tNRFQE",
            "_score": 0.029437244,
            "_source": {
              "title": "Python Essentials",
              "description": "Python Essentials - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.1098,
                0.0933,
                0.0612,
                0.8775
              ]
            }
          }
        ]
      }
    }
    ```

### 類似ベクトル検索（knn）
「専門性が高い本」に近い embedding を持つ上位3件を検索します

1. 下記のコマンドを実行します
    
    ```json
    GET my-vector-index/_search
    {
      "size": 3,
      "query": {
        "knn": {
          "embedding": {
            "vector": [0.1, 0.1, 0.1, 0.9],
            "k": 3
          }
        }
      }
    }
    
    ```

1. 下記の結果が返されました
    ```json
    {
      "took": 38,
      "timed_out": false,
      "_shards": {
        "total": 0,
        "successful": 0,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": {
          "value": 10,
          "relation": "eq"
        },
        "max_score": 0.99969876,
        "hits": [
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AaMLMCZYBtRq-o6tNRFQF",
            "_score": 0.99969876,
            "_source": {
              "title": "Machine Learning Handbook",
              "description": "Machine Learning Handbook - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.1123,
                0.0923,
                0.0914,
                0.9041
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3ATsLMCZYBtRq-o6tNRFQE",
            "_score": 0.9994855,
            "_source": {
              "title": "Java for Professionals",
              "description": "Java for Professionals - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0971,
                0.0913,
                0.0895,
                0.9179
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AKsLMCZYBtRq-o6tNRFQD",
            "_score": 0.99919564,
            "_source": {
              "title": "Big Data From Zero to Hero",
              "description": "Big Data From Zero to Hero - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0913,
                0.102,
                0.0905,
                0.9252
              ]
            }
          }
        ]
      }
    }
    ```

### 条件付き検索（bool）
title に DevOps を含み、かつ description に beginner を含まない条件で検索します

1. 下記を実行します
    ```json
    GET my-vector-index/_search
    {
      "query": {
        "bool": {
          "must": [
            { "match": { "title": "DevOps" } }
          ],
          "must_not": [
            { "match": { "description": "beginner" } }
          ]
        }
      }
    }
    
    ```

1. 下記の結果が返されました
    ```json
    {
      "took": 30,
      "timed_out": false,
      "_shards": {
        "total": 0,
        "successful": 0,
        "skipped": 0,
        "failed": 0
      },
      "hits": {
        "total": {
          "value": 5,
          "relation": "eq"
        },
        "max_score": 3.6306305,
        "hits": [
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AIsLMCZYBtRq-o6tNRFQC",
            "_score": 3.6306305,
            "_source": {
              "title": "DevOps Handbook",
              "description": "DevOps Handbook - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0669,
                0.0532,
                0.1023,
                0.8631
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AQsLMCZYBtRq-o6tNRFQE",
            "_score": 3.207633,
            "_source": {
              "title": "DevOps Principles",
              "description": "DevOps Principles - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0555,
                0.133,
                0.0582,
                0.8911
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3AEsLMCZYBtRq-o6tNRFQC",
            "_score": 2.7861922,
            "_source": {
              "title": "DevOps in Action",
              "description": "DevOps in Action - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0695,
                0.1037,
                0.1464,
                0.932
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3ARsLMCZYBtRq-o6tNRFQE",
            "_score": 2.7861922,
            "_source": {
              "title": "DevOps for Beginners",
              "description": "DevOps for Beginners - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0932,
                0.0961,
                0.0921,
                0.8663
              ]
            }
          },
          {
            "_index": "my-vector-index",
            "_id": "1%3A0%3ALsLMCZYBtRq-o6tNRFQD",
            "_score": 2.5103216,
            "_source": {
              "title": "DevOps From Zero to Hero",
              "description": "DevOps From Zero to Hero - A comprehensive and practical book in the field of software and technology.",
              "embedding": [
                0.0749,
                0.1446,
                0.0961,
                0.8671
              ]
            }
          }
        ]
      }
    }
    ```

# 考察
OpenSearch Serverlessでさまざまな検索クエリ（match、knnなど）を試しました、
今後は、実際の埋め込みデータを用いたベクトル検索や、検索結果の活用方法についても深掘りしていきたいと思います。


# 参考

https://qiita.com/zumax/items/963454f7b9561c1e52df

https://qiita.com/zumax/items/d005dce95f7730220bc5

https://qiita.com/zumax/items/88cbfebcad0041c0799a

https://dev.classmethod.jp/articles/aoss-vector-cfn/

https://docs.aws.amazon.com/ja_jp/opensearch-service/latest/developerguide/serverless-cfn.html