milvus 是一款开源的向量相似度搜索引擎,支持针对 TB 级向量的增删改操作和近实时查询,具有高度灵活、稳定可靠以及高速查询等特点。milvus 还可以对标量数据进行过滤,进一步提高了召回率,增强了搜索的灵活性。
milvus看作是是一个数据库,既然是数据库就需要有位置进行存储,这里使用了docker来安装milvus,之后通过访问docker的ip+port来存储向量和查询向量。
安装前需要在服务器上安装docker工具,方便安装milvus,完成安装过程如下:
#拉取 CPU 版本的 Milvus 镜像
sudo docker pull milvusdb/milvus:0.10.3-cpu-d091720-f962e8
#下载配置文件
mkdir -p /home/$USER/milvus/conf
cd /home/$USER/milvus/conf
wget https://raw.githubusercontent.com/milvus-io/milvus/0.10.3/core/conf/demo/server_config.yaml
#启动 Docker 容器,将本地的文件路径映射到容器中:
sudo docker run -d --name milvus_cpu_0.10.3 \
-p 19530:19530 \
-p 19121:19121 \
-v /home/$USER/milvus/db:/var/lib/milvus/db \
-v /home/$USER/milvus/conf:/var/lib/milvus/conf \
-v /home/$USER/milvus/logs:/var/lib/milvus/logs \
-v /home/$USER/milvus/wal:/var/lib/milvus/wal \
milvusdb/milvus:0.10.3-cpu-d091720-f962e8
#确认 Milvus 运行状态:
sudo docker ps
#如果 Milvus 服务没有正常启动,执行以下命令查询错误日志:
sudo docker logs milvus_cpu_0.10.3
milvus创建连接,需要连接数据库:self.milvus = Milvus(host=132.232.138.21, port=8095)
milvus使用大体可分为两大部分:初始化和查询,其中初始化需要将元数据(未经向量化处理的数据,例如文本,图片)转化为向量,插入到milvus数据库中,初始化过程如下:
初始化时判断集合是否已经存在:
_, has_collection = self.milvus.has_collection(collection_name)
if has_collection:
self.milvus.drop_collection(collection_name)
初始化时创建新集合:
创建集合需要传入的参数集
param = dict(
collection_name=collection_name, # 集合名,对应项目用户名
dimension=dimension, # 向量维度,自定义为100
index_file_size=index_file_size, # 索引文件大小,默认为1024M
metric_type=MetricType.IP # 相似度计算方法,欧式距离为L2,内积为IP
)
status = self.milvus.create_collection(param)
if status.code != 0:
return status
# 创建成功返回结果格式
Status(code=0, message='Create collection successfully!')
初始化时创建索引
status = self.milvus.create_index(collection_name,IndexType.IVF_FLAT,{'nlist': self.N_LIST})
return status
# 创建成功返回结果格式
Status(code=0, message='Build index successfully!')
初始化时插入数据
status, inserted_vector_ids = self.milvus.insert(collection_name=collection_name, records=in_records, ids=in_ids)
if status.code != 0:
elf.delete(collection_name, add_ids)
return status
inserted_vector_ids返回的结果格式为:[1592028661511657000, 1592028661511657001, 1592028661511657002,...]
初始化函数:
def init_vec(self, collection_name):
print('init vec ...')
_, has_collection = self.milvus.has_collection(collection_name)
if has_collection:
self.milvus.drop_collection(collection_name)
# create collection
self.create_collection(collection_name)
# get data
in_ids = []
in_records = []
# insert
status, _ = self.milvus.insert(collection_name=collection_name,
records=in_records,
ids=in_ids)
if status.code != 0:
return status
# create index
status = self.create_index(collection_name)
print('init vec ok')
return status
查询
milvus最终的目的也是最重要的是执行查询,即输入问题与milvus数据库中向量数据库进行查询,并使用返回相似度最大的数据,返回数据格式为:[ id, distance ],id为向量数据的id,distance为问题向量与数据库中数据库采用欧式距离或点积计算的出来的值,还可以制定返回结果的tok个数据
milvus查询核心函数为search()
status, search_rst = self.milvus.search(collection_name=collection_name,
query_records=[question_vec], # 代查询问题的向量化形式
top_k=top_k, # 返回最为相似的前top_k个结果
params={'nprobe': self.N_PROBE}) # 搜索参数,因索引类型不同而不同
# 创建成功返回结果格式,当top_k==2时,query_records为5个32维的向量,结果返回
[
[(id:1592028661511657012, distance:19.450458526611328), (id:1592028661511657017, distance:20.13418197631836)],
[(id:1592028661511657012, distance:19.12230682373047), (id:1592028661511657018, distance:20.221458435058594)],
[(id:1592028661511657014, distance:20.423980712890625), (id:1592028661511657016, distance:20.984281539916992)],
[(id:1592028661511657018, distance:18.37057876586914), (id:1592028661511657019, distance:19.366962432861328)],
[(id:1592028661511657013, distance:19.522361755371094), (id:1592028661511657010, distance:20.304216384887695)]
]
向量数据库在超大量数据中比较好用,大大缩短了数据查询速度,提升了查询速度,可用在亿级数据上,则逐渐在大公司进行使用。
最后总结一下,使用milvus需要注意的问题: