./knowledge-base/docs/opensearch-setup.md

# OpenSearch セットアップガイド

## OpenSearchインデックスの作成

CDKデプロイ後、OpenSearchにインデックスを手動で作成する必要があります。

### 前提条件

- OpenSearchドメインがデプロイ済み
- VPC内からのアクセス(EC2インスタンス、Cloud9、またはVPN経由)

### インデックス作成

#### 1. OpenSearchエンドポイントの取得

```bash
OPENSEARCH_ENDPOINT=$(aws cloudformation describe-stacks \
  --stack-name HistoricalResearchStack \
  --query "Stacks[0].Outputs[?OutputKey=='OpenSearchDomainEndpoint'].OutputValue" \
  --output text)

echo $OPENSEARCH_ENDPOINT
```

#### 2. インデックスの作成

```bash
curl -X PUT "https://${OPENSEARCH_ENDPOINT}/historical-research-pages" \
  -H 'Content-Type: application/json' \
  -d '{
  "settings": {
    "index": {
      "knn": true,
      "knn.algo_param.ef_search": 512,
      "number_of_shards": 2,
      "number_of_replicas": 1
    },
    "analysis": {
      "analyzer": {
        "japanese_analyzer": {
          "type": "custom",
          "tokenizer": "kuromoji_tokenizer",
          "filter": ["kuromoji_baseform", "kuromoji_part_of_speech", "cjk_width", "lowercase"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "page_id": { "type": "keyword" },
      "document_id": { "type": "keyword" },
      "page_number": { "type": "integer" },
      "s3_uri": { "type": "keyword" },
      "thumbnail_uri": { "type": "keyword" },
      
      "user_title": {
        "type": "text",
        "analyzer": "japanese_analyzer",
        "fields": {
          "keyword": { "type": "keyword" }
        }
      },
      "user_era": { "type": "keyword" },
      "user_genre": { "type": "keyword" },
      "user_tags": { "type": "keyword" },
      
      "ai_era": { "type": "keyword" },
      "ai_scene": {
        "type": "text",
        "analyzer": "japanese_analyzer"
      },
      "ai_genre": { "type": "keyword" },
      
      "extracted_text": {
        "type": "text",
        "analyzer": "japanese_analyzer"
      },
      "image_description": {
        "type": "text",
        "analyzer": "japanese_analyzer"
      },
      "page_type": { "type": "keyword" },
      "page_type_confidence": { "type": "float" },
      
      "structured_data": { "type": "object", "enabled": false },
      "entities": {
        "type": "nested",
        "properties": {
          "type": { "type": "keyword" },
          "value": { "type": "text", "analyzer": "japanese_analyzer" },
          "confidence": { "type": "float" }
        }
      },
      "topics": { "type": "keyword" },
      "detected_objects": { "type": "keyword" },
      "era_characteristics": {
        "type": "text",
        "analyzer": "japanese_analyzer"
      },
      
      "integrated_text": {
        "type": "text",
        "analyzer": "japanese_analyzer"
      },
      "text_embedding": {
        "type": "knn_vector",
        "dimension": 1024,
        "method": {
          "name": "hnsw",
          "space_type": "cosinesimil",
          "engine": "nmslib",
          "parameters": {
            "ef_construction": 512,
            "m": 16
          }
        }
      },
      
      "created_at": { "type": "date" },
      "updated_at": { "type": "date" }
    }
  }
}'
```

#### 3. インデックスの確認

```bash
curl -X GET "https://${OPENSEARCH_ENDPOINT}/historical-research-pages/_mapping?pretty"
```

### kNN検索パラメータの説明

- **dimension**: 1024 (Titan Text V2のベクトル次元数)
- **space_type**: cosinesimil (コサイン類似度)
- **engine**: nmslib (高速近似最近傍探索)
- **ef_construction**: 512 (インデックス構築時の精度パラメータ)
- **m**: 16 (HNSWグラフの接続数)
- **ef_search**: 512 (検索時の精度パラメータ)

### テストデータの投入

```bash
curl -X POST "https://${OPENSEARCH_ENDPOINT}/historical-research-pages/_doc/test_001" \
  -H 'Content-Type: application/json' \
  -d '{
  "page_id": "test_001_page_0001",
  "document_id": "test_001",
  "page_number": 1,
  "user_title": "テスト画像",
  "user_era": "昭和40年代(1956年~1965年)",
  "user_genre": ["生活"],
  "user_tags": ["テスト"],
  "created_at": "2026-02-25T00:00:00Z",
  "updated_at": "2026-02-25T00:00:00Z"
}'
```

### インデックスの削除(必要に応じて)

```bash
curl -X DELETE "https://${OPENSEARCH_ENDPOINT}/historical-research-pages"
```

## トラブルシューティング

### アクセス拒否エラー

OpenSearchはVPC内にあるため、パブリックインターネットからはアクセスできません。以下の方法でアクセスしてください:

1. **EC2インスタンスを使用**
   - 同じVPC内のEC2インスタンスからSSHでアクセス
   - curlコマンドを実行

2. **Cloud9を使用**
   - 同じVPC内にCloud9環境を作成
   - ターミナルからcurlコマンドを実行

3. **VPN経由**
   - VPN接続を確立
   - VPC内のリソースにアクセス

### Security Groupの確認

OpenSearchのSecurity Groupで、以下のインバウンドルールが設定されていることを確認:

- ポート: 443 (HTTPS)
- ソース: Lambda関数のSecurity Group

### インデックスが作成されない

- レスポンスにエラーメッセージがないか確認
- OpenSearchのバージョンがkNN検索をサポートしているか確認(2.5以降)

## 参考資料

- [OpenSearch k-NN Plugin Documentation](https://opensearch.org/docs/latest/search-plugins/knn/index/)
- [Amazon OpenSearch Service Developer Guide](https://docs.aws.amazon.com/opensearch-service/)