Amazon CloudSearchとElasticsearchの違いを調べると、2016〜2020年ごろの比較記事が今も上位に並んでいます。どちらもLuceneを土台にした検索エンジンで、「設定が簡単なCloudSearch、自由度の高いElasticsearch」という整理自体は今も正しいものの、2026年の前提は変わりました。CloudSearchは2024年7月25日に新規顧客の受付を終え、「Amazon Elasticsearch Service」は2021年にAmazon OpenSearch Serviceへ改称されています。比較の候補として並べられることの多いAmazon Kendraも、2026年7月30日に新規受付を終了しました。この記事では、両者の機能差を東京リージョンの料金とあわせて整理し、これから選ぶならどれか、CloudSearchを使っている場合にどう移すかを、OpenSearch 3.9で動かしたコードで示します。
まとめ:CloudSearchとElasticsearchの違いと2026年の選び方
- 新規に作るならAmazon OpenSearch Service。旧Amazon Elasticsearch Serviceの後継で、CloudSearchの検索機能に加えてベクトル検索・ログ分析・VPC内への配置ができる。
- CloudSearchは新規に選べない。2024年7月25日で新規受付を終了し、AWSの一覧では「Maintenance」区分。既存の利用は続けられるが新機能は出ない。
- 違いの核心はクエリと集計の自由度。CloudSearchは独自の検索APIと最大200個のフィールド定義(動的フィールドを含む)、OpenSearchはQuery DSLとaggregationsで、マッピングもアナライザーも自分で組める。
- KendraとElasticsearchの比較は、新規案件ではもう成り立たない。Kendraは新規受付を終了しており、AWSは移行先にAmazon Bedrock Managed Knowledge Baseを挙げている。
- サイト内検索を早く出したいならAlgolia、Elasticsearch本家の機能が要るならElastic Cloud(AWS東京リージョンで稼働可)。
CloudSearchとElasticsearch(OpenSearch)の機能比較
CloudSearchはAWSが移行ガイドで「カスタマイズしたApache Solr」で動いていると説明するフルマネージドの検索サービスです。Elasticsearch側は、AWSのマネージド版が2021年9月8日にAmazon OpenSearch Serviceへ改称され、OpenSearchと旧Elasticsearch OSSの両方を動かせるサービスになりました。2026年に比べる相手はOpenSearch Serviceです。
| 項目 | Amazon CloudSearch | Amazon OpenSearch Service |
|---|---|---|
| エンジン | Solrベース(AWS独自) | OpenSearch/Elasticsearch OSS 7.10まで |
| 新規の利用開始 | 不可(2024-07-25終了) | 可 |
| クエリ | simple・structured・lucene・dismax | Query DSL・SQL・PPL |
| 集計 | facet(既定は上位10件) | aggregations(入れ子可) |
| フィールド型 | 11種類(ベクトル型なし) | knn_vector等を含む |
| 日本語 | 解析スキーム_ja_default_ | kuromoji・ICU等を自分で設定 |
| ネットワーク | 公開エンドポイント+ポリシー | VPC内ドメインも可 |
| バッチ上限 | 5 MB/10秒に1回 | _bulkのサイズはインスタンス依存 |
CloudSearchとOpenSearchのクエリ・集計機能の差
CloudSearchのインデックスフィールドは、API仕様上 int・double・literal・text・date・latlon とその配列型の11種類で、ベクトルを入れる型がありません。上限も決まっていて、1ドメインで設定できるインデックスフィールド定義は200まで、式(expression)は50まで、1文書は1 MBまでです。動的フィールドは1定義として数えられ、展開後のフィールド数は200を超える場合があります。ファセットは指定しなければ件数の多い上位10値を返します。
OpenSearchは、マッピングとアナライザーをインデックスごとに定義し、集計の中に集計を入れられます。「カテゴリ別の件数を出し、その中で価格帯ごとに数える」のように条件を重ねた集計を1回のリクエストで返したい、親子関係を持つデータを1つのインデックスで扱いたい、といった要件が1つでもあればOpenSearchを選びます。2016年にCloudSearchからElasticsearchへ移ったTokyo Otaku Modeの開発ブログも、乗り換えの理由の1つに「複数条件のファセットを1回で取得できない」ことを挙げています。
CloudSearchとOpenSearchの自動スケーリング・VPC対応の差
CloudSearchの長所は、インスタンスサイズとレプリカの増減をサービスに任せられることです。一方でアクセス制御はIAMポリシーとドメインのリソースポリシーで行い、公式ガイドはEC2からのアクセスを許可するにはインスタンスのパブリックIPを指定すると説明しています。OpenSearch ServiceはVPC内にドメインを作れるため、検索基盤をインターネットに出したくない社内システムではここが決め手になります。運用の手間を減らしたい場合は、OpenSearch ServiceのServerless版がCloudSearchに近い使い勝手です。
AWSの検索サービスと料金の比較(東京リージョン)
AWS上で検索基盤を選ぶ際の候補は、OpenSearch Service(マネージドクラスタとServerless)、Amazon Kendra、AWS上で動くSaaSのAlgoliaとElastic Cloudです。料金は2026年10月26日にAWS Price List APIから取得した東京リージョン(ap-northeast-1)のオンデマンド単価と、各社の公式料金ページの値で、1か月730時間で計算しています。CloudSearchの単価はCloudSearchの料金ページでも確認できます。
| サービス | 新規受付 | 課金単位 | 最小構成の目安 |
|---|---|---|---|
| CloudSearch | 終了 | インスタンス時間 | search.small $0.082/時=約$59.9/月 |
| OpenSearch Service | 受付中 | インスタンス時間+EBS | t3.small.search $0.056/時=約$40.9/月 |
| OpenSearch Serverless | 受付中 | OCU時間 | $0.334/OCU時(Classic冗長構成は最低2 OCU) |
| Amazon Kendra | 終了 | インデックス時間 | 既存顧客のみ |
| Algolia Grow | 受付中 | 検索回数+レコード数 | 月1万回まで無料・以降$0.50/千回 |
差が出るのはServerlessです。OpenSearch Serviceの料金ページによると、Classicコレクションは最初のコレクションにインデックス用1 OCUと検索用1 OCUの最低2 OCUがかかり、東京では計算リソースだけで$0.668/時=約$488/月です。保存データのストレージ料金は別にかかります。冗長スタンバイを外した開発・テスト構成でも合計1 OCU(約$244/月)です。小さなサイト内検索を「CloudSearchと同じ感覚で」Serverlessへ移すと、費用が数倍に膨らみます。新しいNextGenのコレクショングループは最小OCUを0にでき、グループ内の全コレクションに10分間リクエストが無ければ計算リソースが0 OCUまで縮みます。ただし0 OCUから戻るときは、各コンポーネントへの最初のリクエストに10〜30秒の遅延が出ると同じページに書かれています。夜間に止まる社内向け検索のように初回の待ちを許容できる用途ならNextGen、サイト内検索のように常にすぐ返す必要がある小規模用途ならt3等の小さなマネージドクラスタを選びます。
Algoliaは料金ページでFree・Grow・Grow Plus・Elevateの4プランを掲げ、Growは月1万回の検索と10万レコードを含み、超過分は検索1,000回あたり$0.50です。レコード数が無料枠の10万件以内なら、月10万回の検索料金は超過9万回分の$45です。t3.small.searchのインスタンス料金とほぼ同じ水準です(レコードの超過料金とOpenSearch側のEBS料金は含めていません)。Growのホスティング先はUS・UK・EUと書かれているため、日本国内に置きたい場合は上位プランを営業に確認してください。
KendraとElasticsearch(OpenSearch)の違い
Kendraは、機械学習で自然文の質問意図を読み取り、SharePointやS3など社内のデータソースへのコネクタを備えたエンタープライズ検索です。OpenSearchはクエリもインデックスも自分で設計する汎用の検索・分析エンジンです。かつては「社内文書のQ&AならKendra、それ以外はElasticsearch」と分ければ済みました。
この比較は2026年に前提が崩れています。AWSはKendraの提供状況の変更として、2026年6月30日にメンテナンスモードへ移し、7月30日から新規顧客を受け付けないと告知しました。既存顧客にはバグ修正とセキュリティ更新が続き、移行先と新規の検索アプリの実装先にはAmazon Bedrock Managed Knowledge Base(BMKB)を推奨しています。新規案件で比べるのは「OpenSearch Service か BMKB か」です。検索条件・集計・ランキングを細かく設計するならOpenSearch、コネクタから検索・回答生成までの管理をまとめて任せたいならBMKBを選びます。回答の表示形式だけでなく、検索基盤のどこまでを自社で設計・運用するかで判断します。Kendraの移行手順はKendraの新規受付終了と移行先BMKBの判断、BMKBの実装はAmazon BedrockでRAGを実装する手順で解説しています。
AWS上の検索サービスの用途別選定基準
OpenSearch Serviceによる全文検索・ログ分析・ベクトル検索
日本語の全文検索とアプリログの分析を1つの基盤で持ち、将来セマンティック検索やRAGの検索側も載せたいならOpenSearch Serviceです。AWSで2026年7月30日にOpenSearch 3.7に対応しました。構築手順と料金の詳細はAmazon OpenSearch Serviceの料金体系・構築手順、3系の変更点はOpenSearch 3の新機能と2.xとの違いにまとめています。AWS上の検索基盤の設計から任せたい場合はAWS・Google Cloud・Azureのインフラ構築でも相談を受けています。
Algoliaによるサイト内検索・EC検索の導入
クラスタのサイズ設計やアナライザーの調整を自社で持ちたくない場合はAlgoliaです。タイプミス補正やファセット、クエリサジェストが標準で揃い、フロントエンド用のUIライブラリから組み込めます。ベクトルとキーワードを組み合わせるNeuralSearchは最上位のElevateプランに含まれ、Grow・Grow Plusでは使えません。
Elastic Cloudで利用するElasticsearch本家の機能
OpenSearch Serviceで動くElasticsearchは7.10が上限です。2026年10月6日に9.5.5が出ている本家の機能(ES|QLや最新の機械学習機能など)が必要なら、Elastic社のElastic Cloudを使います。対応リージョンにAWS東京(ap-northeast-1)があり、AWS Marketplace経由で契約するとAWSのリージョンだけを選べます。ライセンスは、Elasticが2024年8月29日にAGPLを選択肢に加えると発表し、無償機能部分のソースコードはSSPL・AGPLv3・Elastic License v2から選べるようになりました。公式配布物のライセンスは引き続きElastic License v2です。
CloudSearchを使い続けてよい条件と移す目安
既存のCloudSearchは、すぐ止まるわけではありません。AWSのServices in Maintenanceの一覧に2024年7月25日付で載っており、終了日を示す「Services in Sunset」の一覧には2026年10月26日時点で載っていません。キーワード一致で足りる小規模な検索で、ベクトル検索もVPC内への配置も予定が無いなら、急いで移す理由はありません。逆に、検索結果の改善要望が溜まっている、フィールドが200に近い、日本語の分割に不満がある、のどれかに当てはまるなら、改修のついでに移すほうが二重の作業を避けられます。
CloudSearchからOpenSearchへの移行手順とコード
AWSの移行ガイドが示すとおり、CloudSearchからOpenSearch Serviceへの移行は、データを再投入してインデックスを作り直す作業になります。以下は、CloudSearchのバッチ形式・structuredクエリ・ファセット・日本語解析をOpenSearchの書き方へ置き換えるコードで、ローカルのOpenSearch 3.9.0(analysis-kuromojiプラグイン入り)で実行し、結果を確かめています。
移行先インデックスとマッピングの作成
以下のcurl例は、localhost:9200へHTTP・認証なしで接続でき、analysis-kuromojiが導入されたローカル検証環境を前提とします。AWS上で実行する場合は接続先を変更し、ドメイン設定に応じてHTTPS・認証・署名を設定してください。最初に、CloudSearchのインデックスフィールドに当たるマッピングを作ります。CloudSearchでliteral型だったフィールドはkeyword、text型だったフィールドはtext、int型は値域を維持するためlongに対応させるのが基本です。以下の年データは32ビット整数に収まるためintegerを使います。自動マッピングに任せると、actorsのような文字列はtext型とactors.keywordサブフィールドの2つになり、完全一致の検索や集計ではactors.keywordを指定することになります。ここではactorsそのものを完全一致で使うため、投入前にkeyword型を明示します。日本語のフィールドには、kuromojiで組んだアナライザーja_textを指定しています。
curl -s -X PUT 'localhost:9200/movies' -H 'Content-Type: application/json' -d '{
"settings": {
"analysis": {
"analyzer": {
"ja_text": {
"type": "custom",
"tokenizer": "kuromoji_tokenizer",
"filter": ["kuromoji_baseform", "kuromoji_part_of_speech", "cjk_width", "ja_stop", "kuromoji_stemmer", "lowercase"]
}
}
}
},
"mappings": {
"properties": {
"title": {"type": "text"},
"title_ja": {"type": "text", "analyzer": "ja_text"},
"year": {"type": "integer"},
"genres": {"type": "keyword"},
"actors": {"type": "keyword"}
}
}
}'
SDFバッチから_bulk形式への変換
CloudSearchの文書バッチは、"type": "add" と "type": "delete" の操作を並べたJSON配列です。OpenSearchの_bulkはNDJSON形式で、index操作は操作行と文書行、delete操作は操作行だけを記述します。次のスクリプトはこの形式へ変換します。検証には、CloudSearchの公式例にならった映画データ4件の追加と1件の削除を並べたバッチ(sdf_batch.json)を使いました。
[
{"type": "add", "id": "tt0076759", "fields": {"title": "Star Wars", "year": 1977, "genres": ["Action", "Adventure"], "actors": ["Harrison Ford", "Mark Hamill"], "title_ja": "スター・ウォーズ 新たなる希望"}},
{"type": "add", "id": "tt0796366", "fields": {"title": "Star Trek", "year": 2009, "genres": ["Action", "Sci-Fi"], "actors": ["Chris Pine", "Zachary Quinto"], "title_ja": "スター・トレック"}},
{"type": "add", "id": "tt2488496", "fields": {"title": "Star Wars: The Force Awakens", "year": 2015, "genres": ["Action", "Sci-Fi"], "actors": ["Harrison Ford", "Daisy Ridley"], "title_ja": "スター・ウォーズ フォースの覚醒"}},
{"type": "add", "id": "tt0084726", "fields": {"title": "Star Trek II", "year": 1982, "genres": ["Sci-Fi"], "actors": ["William Shatner"], "title_ja": "スター・トレック2 カーンの逆襲"}},
{"type": "delete", "id": "tt0484575"}
]
import json
import sys
def sdf_to_bulk(batch, index):
lines = []
for op in batch:
if op["type"] == "add":
lines.append({"index": {"_index": index, "_id": op["id"]}})
lines.append(op["fields"])
elif op["type"] == "delete":
lines.append({"delete": {"_index": index, "_id": op["id"]}})
else:
raise ValueError("unknown type: " + op["type"])
return "\n".join(json.dumps(x, ensure_ascii=False) for x in lines) + "\n"
if __name__ == "__main__":
with open(sys.argv[1], encoding="utf-8") as f:
sys.stdout.write(sdf_to_bulk(json.load(f), sys.argv[2]))
python3 sdf_to_bulk.py sdf_batch.json movies > bulk.ndjson
curl -s -X POST 'localhost:9200/_bulk?refresh=true' -H 'Content-Type: application/x-ndjson' --data-binary @bulk.ndjson
4件の追加と、存在しないIDの削除1件を流した結果は "errors":false で、削除だけが "result":"not_found","status":404 でした。存在しない文書の削除はエラー扱いにならないため、移行スクリプトで件数を検証するときはerrorsだけでなく各行のresultも数えます。CloudSearchの「1バッチ5 MB」の分割単位はそのまま流用できますが、OpenSearch側ではrefresh=trueを付けずに投入し、最後にまとめてリフレッシュするほうが速く終わります。
structuredクエリからQuery DSLへの変換
CloudSearchのstructuredクエリは (and …) (or …) (not …) の前置記法です。OpenSearchではboolクエリのmust・should・must_notに対応します。公式ガイドの例 (and title:'star' (or actors:'Harrison Ford' actors:'William Shatner')(not actors:'Zachary Quinto')) は次のように書けます。
{
"query": {
"bool": {
"must": [
{"match": {"title": "star"}},
{"bool": {"should": [
{"term": {"actors": "Harrison Ford"}},
{"term": {"actors": "William Shatner"}}
], "minimum_should_match": 1}}
],
"must_not": [{"term": {"actors": "Zachary Quinto"}}]
}
}
}
このJSONをquery1.jsonに保存し、curl -s -X POST 'localhost:9200/movies/_search' -H 'Content-Type: application/json' --data-binary @query1.json で送ります。
検証データ4件では、Zachary Quintoが出演する「Star Trek」だけが除かれ3件が返りました。範囲指定は書き方が逆向きになるので注意します。(not (range field=year {,2000})) は「2000未満を除く」意味で、"must_not": [{"range": {"year": {"lt": 2000}}}] に置き換えます。{は端を含まず[は含むため、ltとlteを取り違えると境界の年の文書が消えます。
ファセットからterms集計への置換
CloudSearchの facet.genres={sort:'count',size:5} は、OpenSearchのterms集計 {"size": 0, "aggs": {"genres": {"terms": {"field": "genres", "size": 5}}}} に当たります。この例では、最初のマッピングでkeyword型にしたgenresを集計します。terms集計は数値型・日付型・boolean型・ip型にも対応します。検証では Action 3件・Sci-Fi 3件・Adventure 1件が返りました。
kuromojiによる日本語アナライザーの定義
CloudSearchの日本語は既定の解析スキーム _ja_default_ に任せられます。OpenSearchでもanalysis-kuromojiプラグインが提供する既定のkuromojiアナライザーを指定できますが、ここでは構成を明示するためカスタムアナライザーを定義します。最初に作ったマッピングのja_textがそれで、効き方は_analyzeで確かめられます。
curl -s -X POST 'localhost:9200/movies/_analyze' -H 'Content-Type: application/json' -d '{"analyzer": "ja_text", "text": "スター・ウォーズ フォースの覚醒"}'
「スター・ウォーズ フォースの覚醒」を_analyzeにかけると、このアナライザーは「スター/ウォーズ/フォース/覚醒」の4語を返し、既定のstandardアナライザーは「の」を残したうえで「覚」「醒」を1文字ずつに割りました。日本語のフィールドにアナライザーを指定し忘れると、熟語が1文字単位で索引され、検索の精度が落ちます。ひらがな読みでの検索まで要る場合はkuromoji_readingformの設定例と落とし穴を参照してください。
旧Amazon Elasticsearch Serviceのドメインの延長サポート期限
「Elasticsearch on AWS」を今も旧バージョンで動かしている場合は、移行より先に費用の期限が来ます。OpenSearch Serviceのサポート期限表では、Elasticsearch 1.5・2.3・5.1〜5.5・6.0〜6.7・7.1〜7.8の標準サポートは2025年11月7日に終わり、延長サポートは2027年11月7日まで延びました。ただし2026年8月の告知で、2026年11月7日からこれらのバージョンの延長サポート料金はインスタンス料金と同額になります。インスタンス代が実質2倍になるということです。Elasticsearch 6.8・7.9・7.10は標準サポートが2027年11月7日まで続き、5.6は延長サポートが2028年11月7日まであります。
上げる先にも注意があります。アップグレードの手引きによると、Elasticsearch 7.10以前で作ったインデックスはOpenSearch 3.xでは読めず、上げる前に再インデックスが必要です。OpenSearch 1.3・2.xからは、いったん2.19へ上げてから3.xへ進みます。
よくある質問
OpenSearchとElasticsearchは互換性がありますか?
Elasticsearch 7.10までのAPIとは概ね互換です。OpenSearch Serviceには、バージョン番号を確かめてから接続する旧Elasticsearch OSSのクライアントのために、OpenSearchのバージョンを7.10と報告する「互換モード」があります。Elasticsearch 8・9系の新しいAPIやクライアントとは互換がありません。
Amazon CloudSearchはいつ終了しますか?
2026年10月26日時点で終了日は告知されていません。2024年7月25日に新規受付を終え、AWSの一覧ではMaintenance区分です。既存顧客は今までどおり使え、AWSはセキュリティ・可用性・性能の改善を続けるものの、新機能は追加しないとしています。
Amazon Elasticsearch Serviceは廃止されたのですか?
廃止ではなく改称です。2021年9月8日にAmazon OpenSearch Serviceへ名前が変わり、同じサービスでOpenSearchと旧Elasticsearch OSSの両方を動かせます。
AWSでElasticsearchを使う料金はいくらですか?
OpenSearch Serviceのマネージドクラスタは、東京リージョンでt3.small.searchが1時間$0.056(約$40.9/月)からで、EBSの料金が別にかかります。Serverlessは1 OCUあたり1時間$0.334で、Classicの冗長構成は最低2 OCU、冗長スタンバイなしの開発・テスト構成は最低1 OCUです。NextGenは無通信時に0 OCUまで縮小できます。延長サポート中の旧Elasticsearchバージョンには追加料金がかかります。
AWSで無料に近い形で使える検索はありますか?
本記事で比較したAWS純正の検索サービスには、利用期間や利用量にかかわらず常時無料になるものはありません。OpenSearch自体はApache 2.0のオープンソースなので、EC2やコンテナに自分で立てればソフトウェアの費用はかからず、インフラ代だけになります。検索回数が月1万回以内、レコード数が5万件以内なら、AlgoliaのFreeプランも候補です。