Weaviate（ベクトルDB）とPostgreSQL（RDB）のクエリ比較

# 記事の概要

ベクトルDBを扱い始めると、RDBを触ったことがあるエンジニアなら「SQLのあれをやりたい」と思うことが多いと思うので、Weaviateで使えるクエリを記事としてまとめる。（まだLLMに聞いてもハルシネーションが凄い）

また、環境の都合上「"vectorizer": "none"」の時のクエリを記載する。（「"vectorizer": "text2vec-openai"」というような、エンベディングモデルを指定するときのクエリは少し異なります。）

以下はWeaviateの開発元のドキュメントです。

https://weaviate.io/developers/weaviate

環境構築の方法については、以下の記事を参考にしてください。

https://qiita.com/kongo-jun/items/8be61733db5b3c810866

# WeaviateとPostgreSQLのクエリ比較

## データベース・スキーマの操作

|操作内容  |PostgreSQL  |Weaviate  |
|---|---|---|
|データベースの作成  |```CREATE DATABASE database_name;```  |-  |
|データベースの削除  |```DROP DATABASE database_name;```  |-  |
|スキーマの作成  |```CREATE SCHEMA schema_name;```    |【A-1】  |
|スキーマの削除  |```DROP SCHEMA my_schema CASCADE;```<br>```DROP SCHEMA my_schema RESTRICT;```|-  |
|テーブルのリスト表示  |```SELECT table_name FROM information_schema.tables;```  |【A-2】 |

### 【A-1】
実行クエリ

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
class_obj = {
    "class": "class_name",
    "description": "class description",
    "vectorizer": "none",
    "properties": [
        {
            "name": "question",
            "dataType": ["text"],
            "description": "The question",
        },
    ],
}
client.schema.create_class(class_obj)
```

確認クエリ

```powershell
>>> print(client.schema.get("class_name"))
{'class': 'Class_name', 'description': 'class description', 'invertedIndexConfig': {'bm25': {'b': 0.75, 'k1': 1.2}, 'cleanupIntervalSeconds': 60, 'stopwords': {'additions': None, 'preset': 'en', 'removals': None}}, 'multiTenancyConfig': {'enabled': False}, 'properties': [{'dataType': ['text'], 'description': 'The question', 'indexFilterable': True, 'indexSearchable': True, 'name': 'question', 'tokenization': 'word'}], 'replicationConfig': {'factor': 1}, 'shardingConfig': {'virtualPerPhysical': 128, 'desiredCount': 1, 'actualCount': 1, 'desiredVirtualCount': 128, 'actualVirtualCount': 128, 'key': '_id', 'strategy': 'hash', 'function': 'murmur3'}, 'vectorIndexConfig': {'skip': False, 'cleanupIntervalSeconds': 300, 'maxConnections': 64, 'efConstruction': 128, 'ef': -1, 'dynamicEfMin': 100, 'dynamicEfMax': 500, 'dynamicEfFactor': 8, 'vectorCacheMaxObjects': 1000000000000, 'flatSearchCutoff': 40000, 'distance': 'cosine', 'pq': {'enabled': False, 'bitCompression': False, 'segments': 0, 'centroids': 256, 'trainingLimit': 100000, 'encoder': {'type': 'kmeans', 'distribution': 'log-normal'}}, 'bq': {'enabled': False}}, 'vectorIndexType': 'hnsw', 'vectorizer': 'none'}
```

### 【A-2】

実行クエリ

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
schema = client.schema.get()
class_names = [cls['class'] for cls in schema['classes']]
print(class_names)
```


## テーブルの操作

|操作内容  |PostgreSQL  |Weaviate  |
|---|---|---|
|テーブルの作成  |   ```CREATE TABLE table_name (column1 datatype constraint,column2 datatype constraint,...);```  |【B-1】  |
|テーブルの削除  |```DROP TABLE table_name;```  |【B-2】  |
|テーブルに列を追加  |```ALTER TABLE table_name ADD COLUMN column_name datatype;```  |【B-3】  |
|テーブルに列を削除  |```ALTER TABLE table_name DROP COLUMN column_name;```  |-  |
|列のデータ型変更  |```ALTER TABLE table_name ALTER COLUMN column_name TYPE new_datatype;```  |-  |

### 【B-1】

実行クエリ

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
class_obj = {
    "class": "table_name",
    "vectorizer": "none",
    "description": "既存のスキーマに追加するクラス",
    "properties": [
        {
            "name": "text",
            "dataType": ["string"],
            "description": "テキストデータ"
        }
    ]
}
client.schema.create_class(class_obj)
```

### 【B-2】

実行クエリ

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
client.schema.delete_class("table_name")
```

### 【B-3】

実行クエリ

```python
import requests
import json
url = 'http://localhost:8080/v1/schema/Table_name/properties'
property_data = {
  "dataType": ["string"],
  "description": "The email address of the person",
  "name": "email"
}
headers = {
    'Content-Type': 'application/json',
}
response = requests.post(url, headers=headers, data=json.dumps(property_data))
print(response.text)
```

## データの挿入、更新、削除

|操作内容  |PostgreSQL  |Weaviate  |
|---|---|---|
|データの挿入  |```INSERT INTO table_name (column1, column2, ...) VALUES (value1, value2, ...);```  |【C-1】  |
|データの更新  |```UPDATE table_name SET column1 = value1, column2 = value2, ... WHERE condition;```  |【C-2】  |
|データの削除  |```DELETE FROM table_name WHERE column1 = "condition";```  |【C-3】  |

### 【C-1】

実行クエリ

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
data_object = {
    "text": "sample_text",
    "email": "sample@example.com"
}
client.data_object.create(data_object, "table_name")
````

確認クエリ

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
query = """
{
  Get {
    Table_name {
      text,
      email
    }
  }
}
"""
result = client.query.raw(query)
print(result)
```

### 【C-2】

実行クエリ

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
updated_data_object = {
    "text": "update text",
}
uuid = "2bfc6032-44d0-4c49-bfe5-c5b0c5dc0d5f"
client.data_object.update(updated_data_object, "table_name", uuid)
```
### 【C-3】

実行クエリ

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
client.data_object.delete(
    uuid="2bfc6032-44d0-4c49-bfe5-c5b0c5dc0d5f",
    class_name="table_name",
)
````

## データの選択

|操作内容  |PostgreSQL  |Weaviate  |
|---|---|---|
|データの選択  |```SELECT column1, column2, ... FROM table_name WHERE condition;```  |【D-1】  |
|全データの選択  |```SELECT * FROM table_name;```  |【D-2】  |

### 【D-1】

実行クエリ

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
query = """
{
  Get {
    Table_name(where: {
      operator: Equal
      path: ["text"]
      valueString: "update text"
    }) {
      text,
      email
    }
  }
}
"""
result = client.query.raw(query)
print(result)
````

### 【D-2】

```python
import weaviate
client = weaviate.Client("http://localhost:8080")
query = """
{
  Get {
    Table_name {
      text,
      email
    }
  }
}
"""
result = client.query.raw(query)
print(result)
```