OceanBaseデータベースは、ベクトル型データの格納、ベクトルインデックス、そしてembeddingベクトル検索機能を提供しています。これにより、ベクトル化されたデータをOceanBaseデータベースに保存し、その後の検索処理で利用することが可能になります。
Ollamaは、オープンソースツールであり、GPT-OS、Gemma 3、DeepSeek-R1、Qwen3などの大規模言語モデルをローカル環境で簡単に実行および管理できるようにします。
前提条件
OceanBaseデータベースV4.3.3以降をデプロイし、MySQLモードのテナントを作成していること。テナントの作成後、以下の手順に従って操作します。
環境に使用可能なMySQLテナント、MySQLデータベース、およびアカウントが存在し、データベースアカウントに読み取り書き込み権限が付与されていること。
Python 3.11以降をインストールしていること。
必要な依存関係に従ってください。
python3 -m pip install pyobvector requests sqlalchemy ollama tqdmベクトル検索機能を有効にするために、テナントで
ob_vector_memory_limit_percentage構成パラメータを設定していることを確認してください。V4.3.5 BP3以前のバージョンでは、値として30を設定することを推奨します。V4.3.5 BP3以降のバージョンでは、デフォルト値の0を維持することを推奨します。この構成パラメータをより正確に設定する必要がある場合は、ob_vector_memory_limit_percentage参照してこの値を計算してください。
ステップ1:データベース接続情報を取得する
OceanBaseデータベースのデプロイ担当者または管理者から、該当するデータベース接続文字列を取得します。例:
obclient -h$host -P$port -u$user_name -p$password -D$database_name
パラメータの説明:
$host:OceanBaseデータベースへの接続IPアドレス。OceanBaseデータベースプロキシ(OceanBase Database Proxy、ODP)接続方式ではODPアドレスを使用し、直接接続方式ではOBServerノードのIPアドレスを使用します。$port:OceanBaseデータベースへの接続ポート。ODP接続方式のデフォルトポートは2883で、ODPデプロイ時にカスタマイズ可能です。直接接続方式のデフォルトポートは2881で、OceanBaseデータベースのデプロイ時にカスタマイズ可能です。$database_name:アクセス対象のデータベース名。注意
テナントに接続するユーザーには、データベースに対する
CREATE、INSERT、DROP、およびSELECT権限が付与されている必要があります。ユーザー権限の詳細については、MySQLモードの権限分類を参照してください。$user_name:テナントの接続アカウント。ODP接続の一般的な形式:ユーザー名@テナント名#クラスタ名またはクラスタ名:テナント名:ユーザー名。直接接続方式の形式:ユーザー名@テナント名。$password:アカウントのパスワード。
その他の接続文字列の詳細については、OBClientを使用したOceanBaseテナントへの接続を参照してください。
ステップ2:あなたのAIアシスタントを構築する
環境変数の設定
OceanBase接続情報を取得し、環境変数に設定します。
export OCEANBASE_DATABASE_URL=YOUR_OCEANBASE_DATABASE_URL
export OCEANBASE_DATABASE_USER=YOUR_OCEANBASE_DATABASE_USER
export OCEANBASE_DATABASE_DB_NAME=YOUR_OCEANBASE_DATABASE_DB_NAME
export OCEANBASE_DATABASE_PASSWORD=YOUR_OCEANBASE_DATABASE_PASSWORD
ollamaのインストールとqwen3-embeddingモデルの取得
curl -fsSL https://ollama.ai/install.sh | sh
export PATH="/usr/local/bin:$PATH"
ollama --version
ollama pull qwen3-embedding:latest
サンプルコードスニペット
データの読み込み
ここでは、qwen3-embedding埋め込みモデルを例に、OceanBase Vectorのベクトル検索のよくある質問をプライベートナレッジとし、「#」でファイル内の内容を区切ります。
import requests,os,json,ollama
from tqdm import tqdm
from sqlalchemy import Column, Integer, String
from pyobvector import ObVecClient, VECTOR, IndexParam, l2_distance
# text URL
url = "https://raw.githubusercontent.com/oceanbase/oceanbase-doc/refs/heads/V4.3.5/en-US/640.ob-vector-search/800.ob-vector-search-faq.md"
response = requests.get(url)
text_lines = []
file_text = response.text
text_lines += file_text.split("# ")
def emb_text(text):
response = ollama.embeddings(model="qwen3-embedding", prompt=text)
return response["embedding"]
data = []
for i, line in enumerate(tqdm(text_lines, desc="Creating embeddings")):
data.append({"text": line, "embedding": emb_text(line)})
ベクトルテーブル構造を定義し、ベクトルをOceanBaseに同時に保存する
ollama_oceanbase_demo_documents という名前のテーブルを作成します。このテーブルには、テキストを格納する text 列、埋め込みベクトルを格納する embedding 列、およびベクトルインデックス情報が含まれます。qwen3-embedding を使用して各テキストセグメントの埋め込みベクトルを生成し、OceanBaseに保存します。
OCEANBASE_DATABASE_URL = os.getenv('OCEANBASE_DATABASE_URL')
OCEANBASE_DATABASE_USER = os.getenv('OCEANBASE_DATABASE_USER')
OCEANBASE_DATABASE_DB_NAME = os.getenv('OCEANBASE_DATABASE_DB_NAME')
OCEANBASE_DATABASE_PASSWORD = os.getenv('OCEANBASE_DATABASE_PASSWORD')
client = ObVecClient(uri=OCEANBASE_DATABASE_URL, user=OCEANBASE_DATABASE_USER,password=OCEANBASE_DATABASE_PASSWORD,db_name=OCEANBASE_DATABASE_DB_NAME)
table_name = "ollama_oceanbase_demo_documents"
client.drop_table_if_exist(table_name)
cols = [
Column("id", Integer, primary_key=True, autoincrement=True),
Column("text", String(255), nullable=False),
Column("embedding", VECTOR(4096))
]
# Create vector index
vector_index_params = IndexParam(
index_name="idx_question_embedding",
field_name="embedding",
index_type="HNSW",
distance_metric="l2"
)
client.create_table_with_index_params(
table_name=table_name,
columns=cols,
vidxs=[vector_index_params]
)
print('- Inserting Data to OceanBase...')
client.insert(table_name, data=data)
セマンティック検索
qwen3-embedding埋め込みモデルを使用してクエリテキストの埋め込みベクトルを生成し、その後、クエリテキストの埋め込みベクトルとベクトルテーブル内の各埋め込みベクトルとのL2距離に基づいて、最も関連性の高いドキュメントを検索します。
question = "Which mode supports vector search?"
search_res = client.ann_search(
table_name,
vec_data=emb_text(question),
vec_column_name="embedding",
distance_func=l2_distance,
with_dist=True,
topk=1,
output_column_names=["id","text"],
)
print('- The Most Relevant Document and Its Distance to the Query:')
for row in search_res.fetchall():
print(f' - ID: {row[0]}\n'
f' content: {row[1]}\n'
f' distance: {row[2]}')
期待される結果
- ID: 3
content: Which mode supports vector search?
Vector search is supported only in the MySQL mode of OceanBase Database.
distance: 0.509979758468682