---
# System prepended metadata

title: Microsoft Azure Cosmos DB for MongoDB (vCore) 使用向量搜索
tags: [archived]

---

###### tags: `Wingene`

# Microsoft Azure Cosmos DB for MongoDB (vCore) 使用向量搜索
## 介紹
***Microsoft Azure Cosmos DB for MongoDB*** 是 Azure Cosmos DB 的一種 API，它可以讓使用者在 Cosmos DB 中運行 MongoDB 應用程式，而無需修改代碼。這讓開發者可以利用 Cosmos DB 的全球分佈、多模型和極限擴展的特性，同時還可以使用熟悉的 MongoDB 工具和 SDK。

以下是 Azure Cosmos DB for MongoDB 的一些主要特性：

- **全球分佈：**
Azure Cosmos DB 讓你可以在世界任何地方進行數據分佈，並且可以隨時在地理位置之間進行數據遷移。

- **多模型和多 API**：
除了 MongoDB API，Cosmos DB 還支持 SQL API，Gremlin API（用於圖形資料庫）和 Azure Table API。你可以在同一個資料庫中混合和匹配不同的模型和 API。

- **自動化的數據分區：**
Azure Cosmos DB 自動將你的數據進行分區，以便你可以在高效率和高性能的條件下進行擴展。

- **無休止擴展：**
Cosmos DB 讓你可以無休止地擴展存儲和吞吐量。

- **實時分析：** 
Azure Cosmos DB 支持實時分析，讓你可以對數據進行實時查詢和視覺化。

當你選擇 vCore 模式時，你可以獲得一種基於伺服器的配置，這將提供更多的彈性和控制能力。在 vCore 模式下，你可以選擇特定數量的虛擬核心、記憶體大小、存儲空間，並可選擇是否開啟 Geo-redundancy 或多區域寫入。此模式更適合大規模和生產級別的應用程式，需要更多的控制和彈性。
<br/>
<br/>

## 建立資料庫
首先，我們必須在 Azure 上啟動 Cosmos 的伺服器。要注意的是，我們所需要的**向量搜尋**（**vector search**）只能在 **vCore** 的版本中運作，這是先覽版本（preview）！

所以我們要建立的服務，就是 Azure Cosmos DB for MongoDB (vCore)。
![](https://hackmd.io/_uploads/rkP8Ei3r3.png)

在全部可以配置的方案中我都選了最低配的版本，然而預估的花費仍然是 $175 USD。
<br/>
<br/>

## 安裝 MongoDB shell
接著為了能按照官方網站的教學去建立**向量搜尋**的搜尋方式，我們需要直接透過 MongoDB Shell。我本來希望所有的後端都能夠用 python 完成的，因為這樣比較容易串接 —— 但是 pymongo 現在還有許多的功能尚未與 MongoDB 保持一致。

這是我參考的安裝教學 (主要是 Ubuntu 的)。
https://www.mongodb.com/docs/manual/tutorial/install-mongodb-on-ubuntu/

### 0. 版本確認
MongoDB 的版本是比較需要仔細比對清楚的，例如我所使用的 Ubuntu 22.04 是在 MongoDB 6.0 版本才被支援的。所以以下的安裝是基於 Ubuntu 22.04 + MongoDB 6.0。

### 1. 將公鑰匯入套件管理系統中
如果系統中沒有 **`gnupg`**，可以使用以下指令安裝（The gnupg package in Ubuntu is for GNU Privacy Guard (GnuPG), a free implementation of the OpenPGP standard as defined by RFC4880.）：

```bash!
sudo apt install gnupg
```

接著匯入 MongoDB 的公鑰 GPG Key：
```
curl -fsSL https://pgp.mongodb.com/server-6.0.asc | \
   sudo gpg -o /usr/share/keyrings/mongodb-server-6.0.gpg \
   --dearmor
```

### 2. 建立 MongoDB list file
```
sudo touch /etc/apt/sources.list.d/mongodb-org-6.0.list
sudo echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-6.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/6.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-6.0.list
```

接著重新讀取本地套件資料庫。
```
sudo apt update
```

如此一來就可以正式安裝 MongoDB 套件了。
```
sudo apt install -y mongodb-org
```

（**Optional**）為了防止自動更新意外更新到 MongoDB，可以固定在當前安裝版本上。
```
echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-database hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongodb-mongosh hold" | sudo dpkg --set-selections
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selections
```

<br/>
<br/>

## 連線 Azure Cosmos DB 資料庫
### 1. 設定「網路」設定中的本地端 IP
首先，先從左側欄位找到『**Network**』選項，並將本地端的 IP 添加進在允許連線的 IP 列表（**或是可以設定全開放，但不建議**）。這步驟有按鈕可以一鍵添加。

### 2. 找到連接字串
為了能夠連線到 Azure Cosmos 建立的 DB，我們需要先進入剛剛建立好的 Cosmos 系統，選擇左側欄位的 **Connection strings**。

進去後，我們就會看到一組可供我們於本地端連線的

![](https://hackmd.io/_uploads/BJalri2B2.png)

把這串連接字串複製下來；接下來我們就可以透過 mongosh 直接連線 Cosmos DB 了。要記得，直接複製的字串上還有需要填寫的**使用者名稱**跟**密碼**，要填寫正確才能連線喔！


### 3. 連線到 Cosmos DB
打開終端機，輸入：
```
mongosh "<YOUR_CONNECTION_STRING>"
```

<br/>
<br/>

## 向量搜尋
### 1. 建立 collection
這段我會推薦直接使用 mongo shell 來做，理由如第一段所述。 
```javascript
use test;

db.runCommand({
   createIndexes: 'exampleCollection',
   indexes: [
     {
       name: 'vectorSearchIndex',
       key: {
         "vectorContent": "cosmosSearch"
       },
       cosmosSearchOptions: {
         kind: 'vector-ivf',
         numLists: 100,
         similarity: 'COS',
         dimensions: 3
       }
     }
   ]
 });
```

- **exampleCollection**： 是我們建立的 collection 名稱
- **vectorContent**： 等等就是我們要放入向量的欄位名稱，可以自己改動，但是後面的 cosmosSearch 是固定的
- **numLists**： 是我們放入資料的數量，官方建議設定大一點
- **similarity**： 是我們的向量搜尋演算法，有 COS (餘弦距離)、L2 (歐式距離)、IP (內部乘績) 可以選擇

<br/>

### 2. 放入資料
這步驟我會推薦使用 python 來做，如果我們所需要放入的資料很多的情況，使用程式語言自動放入資料是比較輕鬆的作法。

首先安裝 pymongo。
```
pip3 install pymongo
```

接著連線到資料庫，並且放入資料：
```python=
from pymongo import MongoClient


# Connect to Azure Cosmos DB
connecting_string = "<YOUR_CONNECTION_STRING>"
client = MongoClient(connecting_string)

# Get the collection we want to insert data
db = client["test"]
collection = db["exampleCollection"]

# Prepare data
docs = [
    {
        "name": "Eugenia Lopez", 
        "bio": "Eugenia is the CEO of AdvenureWorks.", 
        "vectorContent": [0.51, 0.12, 0.23],
    },
    {
        "name": "Cameron Baker", 
        "bio": "Cameron Baker CFO of AdvenureWorks.", 
        "vectorContent": [0.55, 0.89, 0.44],
    },
    {
        "name": "Jessie Irwin", 
        "bio": "Jessie Irwin is the former CEO of AdventureWorks and now the director of the Our Planet initiative.", 
        "vectorContent": [0.13, 0.92, 0.85],
    },
    {
        "name": "Rory Nguyen", 
        "bio": "Rory Nguyen is the founder of AdventureWorks and the president of the Our Planet initiative.", 
        "vectorContent": [0.91, 0.76, 0.83],
    },
]

# Insert
result = collection.insert_many(docs)
print(f"Inserted document ids: {result.inserted_ids}")
```

<br>
<br>


### 3. 透過向量查詢資料
```python=
# Define the query vector
queryVector = [-0.52, 0.28, 0.12]

# Define the aggregate query
query = [
    {
        "$search": {
            "cosmosSearch": {
                "vector": queryVector,
                "path": "vectorContent",
                "k": 3
            },
            "returnStoredSource": True
        }
    }
]

# Execute the aggregate query
results = collection.aggregate(query)

# Print the results
for result in results:
    print(result)
```
<br/>
<br/>

---
## References
- [Quickstart: Create an Azure Cosmos DB for MongoDB vCore cluster by using the Azure portal](https://learn.microsoft.com/en-us/azure/cosmos-db/mongodb/vcore/quickstart-portal)
- [Using vector search on embeddings in Azure Cosmos DB for MongoDB vCore](https://learn.microsoft.com/en-us/azure/cosmos-db/mongodb/vcore/vector-search)