Milvus使用指南 (下)

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 表示输出的实体中展示哪些字段。

相关推荐
郝亚军4 小时前
ec_private.pem的生成方法
linux·运维·服务器
NendoZen5 小时前
Arch Linux解决Grub无法SAVEDEFAULT问题(uki启动问题)
linux·运维·服务器
文丑颜不良啊5 小时前
LeetCode201~225题目解析
java·leetcode
智能直播6 小时前
RK3518:1.5G 内存 + 8G 存储,如何跑起硬件编解码、Web、AI 识别、绿幕特效
前端·人工智能·5g
Elastic 中国社区官方博客6 小时前
Elasticsearch:安装自行管理的 Elastic Stack 集群
大数据·运维·服务器·数据库·elasticsearch·搜索引擎·全文检索
忆挽篱笙歌6 小时前
进程控制管理
linux·运维·服务器
掘金酱7 小时前
【10.24 特别活动】AI 时代,程序员的新饭碗在哪里?
前端·人工智能·后端
SL_staff7 小时前
4G设备掉线三层归因指南:SIM卡、模组、JVS-IOT网关配置精准锁定
java·物联网·产品
excel7 小时前
多进程环境下使用 PM2 部署 Socket.IO:需要注意什么
前端
IT_陈寒7 小时前
Redis的原子性竟然失效了?记一次分布式锁翻车实录
前端·人工智能·后端