OpenSearch 向量語意搜尋實作指南
這篇教你用 OpenSearch 建立向量語意搜尋,完成索引、寫入嵌入向量、相似度查詢與混合搜尋。

這篇教你用 OpenSearch 建立向量語意搜尋,完成索引、寫入嵌入向量、相似度查詢與混合搜尋。
這篇給想把文件搜尋、知識庫或商品搜尋升級成語意搜尋的開發者。你會照著做出一個可用的 OpenSearch 向量索引,能存文字與 embedding,並回傳最近鄰結果。
完成後,你會拿到一組可直接改成正式專案的指令、索引設定與查詢範本,方便你把語意檢索接到自己的應用程式。
開始之前
訂閱 AI 趨勢週報
每週精選模型發布、工具應用與深度分析,直送信箱。不定期,不騷擾。
不會寄垃圾信,隨時可取消。
- OpenSearch 2.x 以上
- OpenSearch Dashboards 2.x 以上,若你想用介面檢查查詢
- Node 20+ 或 Python 3.10+,若你要在應用程式內產生 embedding
- Docker 24+ 或可透過 HTTP 存取的 OpenSearch 叢集
- OpenSearch 管理員帳號與密碼,或 API key
- 一個 embedding 模型或 embedding API,例如 OpenAI、Cohere 或 Amazon Bedrock
- curl 8+,用來執行本文範例
Step 1: 啟動 OpenSearch 叢集
這一步的目的是先拿到一個可連線的 OpenSearch 端點,讓你後面可以建立向量欄位與搜尋查詢。若你是本機開發,直接用 Docker 起單節點最省事。

docker run -p 9200:9200 -p 9600:9600 \
-e "discovery.type=single-node" \
-e "OPENSEARCH_INITIAL_ADMIN_PASSWORD=StrongPassword123!" \
opensearchproject/opensearch:latest驗收方式很簡單,請用瀏覽器或 curl 打開根端點。你應該看到叢集名稱、版本資訊,以及可連線的回應內容。
Step 2: 建立向量索引
這一步的產出是可以同時存文字與向量的索引。你要先定義 knn_vector 欄位,維度必須和你的 embedding 模型輸出一致,例如 384、768 或 1536。

curl -u admin:StrongPassword123! -X PUT "https://localhost:9200/articles" -k -H 'Content-Type: application/json' -d '
{
"settings": {
"index": {
"knn": true
}
},
"mappings": {
"properties": {
"title": { "type": "text" },
"body": { "type": "text" },
"body_vector": {
"type": "knn_vector",
"dimension": 384
}
}
}
}'驗收時,請查詢索引 mapping。你應該看到 knn_vector 欄位,而且維度就是你剛剛設定的數字。
Step 3: 寫入文件與 embedding
這一步的產出是已經帶有文字與數值向量的文件資料。先在你的應用程式裡產生 embedding,再把每筆文件連同向量一起送進 OpenSearch。
curl -u admin:StrongPassword123! -X POST "https://localhost:9200/articles/_doc/1?refresh=true" -k -H 'Content-Type: application/json' -d '
{
"title": "向量搜尋入門",
"body": "OpenSearch 可以儲存 embedding 來做語意檢索。",
"body_vector": [0.12, -0.03, 0.44, 0.08]
}'驗收方式是把剛寫入的文件取回來。你應該看到文字欄位與向量欄位都已經出現在回應裡。
Step 4: 執行最近鄰查詢
這一步的產出是可用於語意搜尋的相似文件結果。你要用同一個 embedding 模型產生查詢向量,然後請 OpenSearch 找出最接近的文件。
curl -u admin:StrongPassword123! -X GET "https://localhost:9200/articles/_search" -k -H 'Content-Type: application/json' -d '
{
"size": 3,
"query": {
"knn": {
"body_vector": {
"vector": [0.10, -0.01, 0.40, 0.05],
"k": 3
}
}
}
}'驗收時,請看前幾筆結果是否在語意上最接近查詢內容,而不只是字面關鍵字相同。
Step 5: 合併文字與向量訊號
這一步的產出是混合搜尋查詢,能同時兼顧精確字詞與語意相似度。當你想讓關鍵字影響排序時,就把文字查詢和向量查詢放在一起。
curl -u admin:StrongPassword123! -X GET "https://localhost:9200/articles/_search" -k -H 'Content-Type: application/json' -d '
{
"query": {
"bool": {
"should": [
{ "match": { "body": "語意檢索" } },
{
"knn": {
"body_vector": {
"vector": [0.10, -0.01, 0.40, 0.05],
"k": 3
}
}
}
]
}
}
}'驗收方式是對照純文字搜尋與純向量搜尋的結果。你應該看到同時符合兩種訊號的文件排得更前面。
| 指標 | 基準/優化前 | 結果/優化後 |
|---|---|---|
| 搜尋方式 | 只用關鍵字比對 | 文字 + 向量混合搜尋 |
| 結果相關性 | 容易漏掉同義詞與近義表達 | 可抓到語意相近文件 |
| 索引內容 | 只有純文字欄位 | 文字欄位 + embedding 向量 |
| 查詢彈性 | 只能依字面命中排序 | 可調整 k 與 should 權重 |
常見錯誤
- 向量維度設錯。修法是把索引 mapping 的 dimension 改成和 embedding 模型輸出完全一致。
- 索引與查詢用了不同 embedding 模型。修法是固定同一個模型家族與前處理流程,避免向量空間不一致。
- 測試時看不到新文件。修法是暫時加上
?refresh=true,或等待 production 的 refresh 週期。
接下來可以看什麼
基礎流程跑通後,下一步可以研究重排序、混合檢索權重調整,以及如何把 OpenSearch 向量搜尋接到正式的知識庫或商品搜尋服務。