4.2 DML操作
确保已删除名为 docs 的collection,下文会重新创建
1 准备嵌入模型
from langchain.embeddings import init_embeddings
from dotenv import load_dotenv
import os
load_dotenv(override=True)
DASHSCOPE_API_URL=os.getenv("DASHSCOPE_API_URL")
DASHSCOPE_API_KEY = os.getenv("DASHSCOPE_API_KEY")
embedding1=embeddings = init_embeddings(
model="qwen3.7-text-embedding",
provider="openai",
api_key=DASHSCOPE_API_KEY,
base_url=DASHSCOPE_API_URL,
check_embedding_ctx_length=False,
)
2 准备collection
① 创建collection
collection_name='docs'
MilsClient.create_collection(
collection_name=collection_name,
dimension=1024,
metric_type="COSINE",
)
根据模型维度,创建匹配的collection。
② 查看collection元数据
from rich import print as rprint
metadate=MilsClient.describe_collection(
collection_name=collection_name,
)
rprint(metadate)
输出如下
{ 'collection_name': 'docs', 'auto_id': False, 'num_shards': 1, 'description': '', 'fields': [ { 'field_id': 100, 'name': 'id', 'description': '', 'type': <DataType.INT64: 5>, 'params': {}, 'is_primary': True }, { 'field_id': 101, 'name': 'vector', 'description': '', 'type': <DataType.FLOAT_VECTOR: 101>, 'params': {'dim': 1024} } ], 'functions': [], 'aliases': [], 'collection_id': 468890752108379173, 'consistency_level': 2, 'consistency_level_name': 'Bounded', 'properties': {'timezone': 'UTC', 'namespace.sharding.enabled': 'false', 'max_field_id': '102'}, 'num_partitions': 1, 'enable_dynamic_field': True, 'enable_namespace': False, 'schema_version': 0, 'created_timestamp': 468891647383437330, 'update_timestamp': 468891647383437330 }
我们在创建collection时没有指定schema,后者可以理解为表结构,此时Milvus会将collection定义为默 认结构。字段信息如下
id :数据ID,作为主键唯一标识数据
vector :数据的嵌入向量
此外, enable_dynamic_field 为 True ,这表示 collection 支持动态字段。也就是说,除了预定义的 id 和 vector 字段之外,在插入数据时还可以携带其他未提前声明的字段,这些字段会被自动写入 并 统一存储在动态字段 中。这样做的好处是能够在不修改 schema 的情况下,灵活保存额外的业务属 性,例如文本内容、标签、时间戳或来源信息等,适合字段结构不固定的场景。
3 准备数据
① 准备原始数据
# 准备测试数据
texts = [
"LangChain 是一个用于构建 LLM 应用的开发框架。",
"Milvus 是一个适合 AI 应用的向量数据库。",
"RAG 的核心是先检索相关知识,再让大模型生成答案。",
"Docker Desktop 可以方便地在本地运行 Milvus Standalone。"
]
② 生成嵌入向量
vectors=embedding1.embed_documents(texts)
③ 查看生成的嵌入向量
print(len(vectors))
print(len(vectors[0]))
print(vectors[0][:5])
④ 封装为可以插入的数据格式
由上可知,collection需要 id字段 作为主键唯一标识数据,需要 vector字段 存储嵌入向量,其余字段 可以按需添加。
data=[
{
"id": i,
"vector":vectors[i],
'text':texts[i],
"score":"demo"
} for i in range(len(texts))
]
4 写入数据
① 插入数据
upsert=MilsClient.upsert(
collection_name=collection_name,
data=data,
)
print("upsert:",upsert)
upsert可以保证幂等写入,即主键相同时覆盖
② 手动flush
Milvus不会第一时间将数据落盘,要看到写入效果,我们手动flush,将数据刷写到磁盘
MilsClient.flush(collection_name=collection_name)
③ 查看collection统计信息
stats=MilsClient.get_collection_stats(collection_name=collection_name)
print(stats)
4.3 DQL操作
1 扫描数据
通过 query_iterator 扫描collection下的所有数据
iterator = MilsClient.query_iterator(
collection_name=collection_name,
filter="",
output_fields=["*"]
)
i = 0
while True:
rows = iterator.next()
if not rows:
break
for row in rows:
print(f"\n第 {i + 1} 条数据")
print(f"id: {row['id']}")
print(f"vector: {row['vector'][:5]}...")
print(f"text: {row['text']}")
print(f"score: {row['score']}")
i += 1
iterator.close()
2 通过主键查询数据
res = MilsClient.get(
collection_name=collection_name,
ids=[0, 1, 2],
)
print(len(res))
for i in range(len(res)):
row = res[i]
print(f"\n第 {i + 1} 条数据")
print(f"id: {row['id']}")
print(f"vector: {row['vector'][:5]}...")
print(f"text: {row['text']}")
print(f"score: {row['score']}")
3 相似度检索
① 准备查询嵌入
query="啥是向量数据库"
query_vector=embedding1.embed_query(query)
② 检索
re = MilsClient.search(
collection_name=collection_name,
data=[query_vector],
limit=3,
output_fields=["*"]
)
print(len(res))
for i in range(len(res)):
row = res[i]
print(f"\n第 {i + 1} 条数据")
print(f"id: {row['id']}")
print(f"vector: {row['vector'][:5]}...")
print(f"text: {row['text']}")
print(f"score: {row['score']}")
limit 表示检索结果最多保留几条数据
output_fields 表示输出的实体中展示哪些字段。