向量数据库Milvus字符串查询

        因为项目需要,用到了向量数据库Milvus,刚开始都没有遇到问题,直到一个表的主键是字符串(VARCHAR),在查询时刚好要以该主键作为查询条件,此时会出现异常,特此记录一下。

        记住,字符串查询,构建表达式时要加上单引号,比如下面的'{face_id}',其实face_id本来就是一个字符串类型了,如果不加会出现如下的异常:
        # pymilvus.exceptions.MilvusException: <MilvusException: (code=65535, message=cannot parse expression: face_id == 2_0, error: invalid expression: face_id == 2_0)>

  具体看下面的代码(milvus_demo.py),其中exists()函数中构建查询表达式时做了特殊处理:

from pymilvus import connections, FieldSchema, CollectionSchema, DataType, Collection, utility, Partition
import asyncio
import time
from datetime import datetime
import math
from typing import List#用于测试字符串查询的demo# MILVUS向量数据库地址
MILVUS_HOST_ONLINE = '127.0.0.1'
MILVUS_PORT = 19530# 检索时返回的匹配内容条数
VECTOR_SEARCH_TOP_K = 100class MilvusAvatar:# table_name 表名# partition_names  分区名,使用默认即可def __init__(self, mode, table_name, *, partition_names=["default"], threshold=1.1, client_timeout=3):self.table_name = table_nameself.partition_names = partition_namesself.host = MILVUS_HOST_ONLINEself.port = MILVUS_PORTself.client_timeout = client_timeoutself.threshold = thresholdself.sess: Collection = Noneself.partitions: List[Partition] = []self.top_k = VECTOR_SEARCH_TOP_Kself.search_params = {"metric_type": "L2", "params": {"nprobe": 256}}self.create_params = {"metric_type": "L2", "index_type": "IVF_FLAT", "params": {"nlist": 2048}}self.init()@propertydef fields(self):fields = [FieldSchema(name='face_id', dtype=DataType.VARCHAR, max_length=640, is_primary=True, auto_id = False),FieldSchema(name='media_id', dtype=DataType.INT64),FieldSchema(name='file_path', dtype=DataType.VARCHAR, max_length=640),  #原图片保存路径FieldSchema(name='name', dtype=DataType.VARCHAR, max_length=640),  #姓名FieldSchema(name='count', dtype=DataType.INT64),  #数量FieldSchema(name='save_path', dtype=DataType.VARCHAR, max_length=640),  #现保存的绝对路径,包含文件名FieldSchema(name='embedding', dtype=DataType.FLOAT_VECTOR, dim=512) ]return fields@propertydef output_fields(self):return ['face_id','media_id', 'file_path', 'name', 'count', 'save_path','embedding']def init(self):try:connections.connect(host=self.host, port=self.port)  # timeout=3 [cannot set]if utility.has_collection(self.table_name):self.sess = Collection(self.table_name)print(f'collection {self.table_name} exists')else:schema = CollectionSchema(self.fields)print(f'create collection {self.table_name} {schema}')self.sess = Collection(self.table_name, schema)self.sess.create_index(field_name="embedding", index_params=self.create_params)for index in self.partition_names:if not self.sess.has_partition(index):self.sess.create_partition(index)self.partitions = [Partition(self.sess, index) for index in self.partition_names]print('partitions: %s', self.partition_names)self.sess.load()except Exception as e:print(e)def query_expr_sync(self, expr, output_fields=None, client_timeout=None):if client_timeout is None:client_timeout = self.client_timeoutif not output_fields:output_fields = self.output_fieldsprint(f"MilvusAvatar query_expr_sync:{expr},output_fields:{output_fields}")print(f"MilvusAvatar num_entities:{self.sess.num_entities}")if self.sess.num_entities == 0:return []return  self.sess.query(partition_names=self.partition_names, output_fields=output_fields,expr=expr,_async= False,offset=0, limit=1000)# emb 为一个人脸特征向量def insert_avatar_sync(self, face_id, media_id, file_path, name, save_path, embedding):print(f'now insert_avatar {file_path}')print(f'now insert_avatar {file_path}')data = [[] for _ in range(len(self.sess.schema))] data[0].append(face_id)data[1].append(media_id)data[2].append(file_path)data[3].append(name)data[4].append(1)data[5].append(save_path)data[6].append(embedding)# 执行插入操作try:print('Inserting into Milvus...')self.partitions[0].insert(data=data)print(f'{file_path}')print(f"MilvusAvatar insert_avatar num_entities:{self.sess.num_entities}")except Exception as e:print(f'Milvus insert media_id:{media_id}, file_path:{file_path} failed: {e}')print(f'Milvus insert media_id:{media_id}, file_path:{file_path} failed: {e}')return Falsereturn True    # embs是一个数组def search_emb_sync(self, embs, expr='', top_k=None, client_timeout=None):if self.sess is None:return Noneif not top_k:top_k = self.top_kmilvus_records = self.sess.search(data=embs, partition_names=self.kb_ids, anns_field="embedding",param=self.search_params, limit=top_k,output_fields=self.output_fields, expr=expr, timeout=client_timeout)print(f"milvus_records:{milvus_records}")return milvus_records   def exists(self,face_id):print(f"exists:{face_id},{type(face_id)}")# 记住,字符串查询,构建表达式时要加上单引号,比如下面的'{face_id}',其实face_id本来就是一个字符串类型了,如果不加会出现如下的异常:# pymilvus.exceptions.MilvusException: <MilvusException: (code=65535, message=cannot parse expression: face_id == 2_0, error: invalid expression: face_id == 2_0)>res = self.query_expr_sync(expr=f"face_id == '{face_id}'", output_fields=self.output_fields)#print(f"exists:{res},{len(res)}")if len(res) > 0: return Truereturn False# 修改照片数    def add_count(self, face_id):res = self.query_expr_sync(expr=f"face_id == '{face_id}'", output_fields=self.output_fields)self.sess.delete(expr=f"face_id == '{face_id}'")for result in res:media_id = result['media_id']file_path = result['file_path']name = result['name']count = int(result['count'])save_path = result['save_path']embedding = result['embedding']data = [[] for _ in range(len(self.sess.schema))] data[0].append(face_id)data[1].append(media_id)data[2].append(file_path)data[3].append(name)data[4].append(count + 1)data[5].append(save_path)data[6].append(embedding)    print(f"add_count face_id:{face_id},file_path:{file_path}, count:{count}")# 执行插入操作try:print('Inserting into Milvus...')self.partitions[0].insert(data=data)except Exception as e:print(f'Milvus insert media_id:{media_id}, file_path:{file_path} failed: {e}')return False                def delete_collection(self):print("delete_collection")self.sess.release()utility.drop_collection(self.table_name)def delete_partition(self, partition_name):print("delete_partition")part = Partition(self.sess, partition_name)part.release()self.sess.drop_partition(partition_name)def query_all(self,limit=None):res = self.sess.query(partition_names = self.partition_names, output_fields = ["face_id","media_id", "name", "count", "save_path"],expr= f"face_id != ''",_async = False,offset = 0, limit = None)print(res)return resif __name__ == "__main__":milvus_avatar= MilvusAvatar("local", "avatar", partition_names=["avatar"])media_id = 2index = 0face_id = f"{media_id}_{index}"file_path = "/home/data/bbh.jpg"save_path = "/home/data/bbh_avatar.jpg"embedding = [i/1000 for i in range(512)]milvus_avatar.insert_avatar_sync(face_id, media_id, file_path, "bbh", save_path, embedding)#result = milvus_avatar.query_all()#print(result)print(milvus_avatar.exists(face_id))

执行:python milvus_demo.py

如果是针对非字符串字段进行查询,则无需做上面的特殊处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/694077.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何理解CSS的边框宽度?

CSS 边框宽度学习手记 CSS 边框宽度小概念 在CSS的世界里&#xff0c;border-width这个属性真的很实用&#xff0c;它能帮我指定HTML元素四周边框的宽度。这个宽度嘛&#xff0c;可以用像素px、点pt、厘米cm、相对单位em这些来表示&#xff0c;很方便吧&#xff01;还有呢&am…

算法竞赛STL:array的使用方法

算法竞赛STL&#xff1a;array的使用方法 文章目录 算法竞赛STL&#xff1a;array的使用方法array array 容器描述&#xff1a; array是一种固定大小的容器&#xff0c;它包含指定数量的元素。每个元素都有一个非负整数索引&#xff0c;用于访问或修改它。 使用方法&#xff…

Camunda和SpringBoot的兼容版本

官网 https://docs.camunda.org/manual/7.15/user-guide/spring-boot-integration/version-compatibility/ Camunda和SpringBoot的兼容版本

iOS面试:2.操作系统

1. 什么是虚拟内存&#xff1f;有什么作用&#xff1f; 虚拟内存是计算机系统中的一种技术&#xff0c;它允许操作系统将部分硬盘空间用作临时的内存扩展&#xff0c;以满足程序运行时的内存需求。虚拟内存的主要作用是扩展计算机的内存空间&#xff0c;使得系统能够同时运行更…

26进制问题

一、问题描述 Excel地址 二、算法简析 本题要求我们将十进制转换为二十六进制。与正常的二十六进制&#xff08;数由 0 , 1 , . . . , 25 0, 1, ..., 25 0,1,...,25 组成&#xff09;不同&#xff0c;本题的二十六进制没有 0 0 0。由题意&#xff0c; ( 1 ) 10 A , ( 2 )…

微信小程序uniapp劳务咨询系统知识百科考试系统java+python+nodejs+php均支持

使用劳务咨询服务平台小程序的分别管理员和用户二个权限子模块。 管理员所能使用的功能主要有&#xff1a;首页、个人中心、用户管理、百科分类管理、知识百科管理、地区信息管理、劳务需求管理、试卷管理、试题管理、论坛交流、系统管理、考试管理等。 用户用户端可以实现首页…

更改WordPress作者存档链接author和Slug插件Edit Author Slug

WordPress默认所有用户的存档永久链接都是/author/username/&#xff0c;不管是管理员还是订阅者或贡献者或作者或编辑。如果你想要自定义用户存档链接&#xff0c;比如根据角色不同使用不一样的author&#xff0c;或者自定义作者链接中的用户名Slug&#xff0c;那么建议考虑使…

【Deep Learning 7】深度可分离卷积

&#x1f31e;欢迎来到Pytorch的世界 &#x1f308;博客主页&#xff1a;卿云阁 &#x1f48c;欢迎关注&#x1f389;点赞&#x1f44d;收藏⭐️留言&#x1f4dd; &#x1f31f;本文由卿云阁原创&#xff01; &#x1f4c6;首发时间&#xff1a;&#x1f339;2024年2月21日&a…

spark sql 的join调优

背景 spark sql中join操作是最耗费性能的操作&#xff0c;因为这涉及到数据的shuffle操作&#xff0c;如果由此导致数据倾斜更是会雪上加霜&#xff0c;那么如何优化join操作的性能呢&#xff1f; join优化 方式一 broadcast广播&#xff1a; 如果是大表和小表的join操作&a…

CTFshow web(sql注入171-175)

web171 还得先爆表名 -1 union select 1,2,group_concat(table_name) from information_schema.tables where table_schema database()-- 注意这里已经提示你了&#xff0c;只要知道是ctfshow_user&#xff0c;就可以拿到flag -1 union select 1,2,password from ctfshow_user…

Python第十九章(模块)

系统的模块库一般处于外部库中的Lib里面 一。导入模块的方式&#xff1a; 1.方式一&#xff1a; 导入&#xff1a;import 模块名1&#xff0c;模块名2 调用&#xff1a;模块名 . 功能名() 2.方式二&#xff1a; 导入&#xff1a;from 模块名 import 功能1&#xff0c;功能…

(每日持续更新)jdk api之ObjectOutput基础、应用、实战

博主18年的互联网软件开发经验&#xff0c;从一名程序员小白逐步成为了一名架构师&#xff0c;我想通过平台将经验分享给大家&#xff0c;因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验&#xff0c;晚上进行用心精简、整理、总结、定稿&…

2024.2.21

1、用多线程进行文件拷贝 #include<myhead.h>//参数结构体创建 typedef struct INFO {const char *srcfile;const char *destfile;int length; }Info;//定义获取文件长度的函数 int get_file_len(const char *srcfile,const char *destfile){int srcfd,destfd;//只读形式…

基于vue的个性化推荐餐饮系统Springboot

项目&#xff1a;基于vue的个性化推荐餐饮系统Springboot 摘要 现代信息化社会下的数据管理对活动的重要性越来越为明显&#xff0c;人们出门可以通过网络进行交流、信息咨询、查询等操作。网络化生活对人们通过网上购物也有了非常大的考验&#xff0c;通过网上进行点餐的人也…

ctfshow web入门 web141-145

1.web141 ^\w$表示在开头和末尾匹配字母数字_&#xff0c;传入的v3值不能有字母数字_&#xff0c;即无字母的命令执行 php中1-phpinfo()是可以执行的&#xff0c;加减乘除都可以实现 这里或&#xff0c;异或&#xff0c;取反等运算都可以 这里采用羽师傅的异或脚本生成paylo…

用十篇论文聊聊关于使用LLM做query Rewrite的问题

一、什么是query改写&#xff1f; query改写其实理解起来很简单&#xff0c;就是把原始的query经历一系列的操作&#xff0c;然后变成另外一个query&#xff0c;从而达到提升召回率和准确率的效果。 query改写的过程中&#xff0c;这一系列的操作&#xff0c;其实是围绕两个方面…

网络原理 - HTTP/HTTPS(4)

HTTP响应详解 认识"状态码"(status code) 状态码表示访问一个页面的结果.(是访问成功,还是失败,还是其它的一些情况...).(响应结果如何) 学习状态码 -> 为了调试问题. 写服务器时,按照状态码的含义正确使用. 200 OK 这是最常见的状态码,表示访问成功. 抓包抓…

面试经典150题——单词规律

"Dont wait. The time will never be just right." - Napoleon Hill 1. 题目描述 2. 题目分析与解析 首先还是得把题目先读懂&#xff0c;我们直接来看看示例&#xff1a; 根据上面的示例&#xff0c;我们可以看出pattern其实就是表示单词出现的规律&#xff0c;每…

Linux中alarm/setitimer函数(信号函数)

alarm函数 函数原型&#xff1a; unsigned int alarm(unsigned int seconds); 函数描述&#xff1a;设置定时器&#xff08;闹钟&#xff09;。在指定seconds后&#xff0c;内核会给当前进程发送 14&#xff09;SIGALRM信号。进程收到该信号&#xff0c;默认动作终止。每个进程…

【栈】LCR 036. 逆波兰表达式求值

LCR 036. 逆波兰表达式求值 解题思路 初始化栈&#xff1a; 创建一个整数栈用于存储操作数。 遍历表达式数组&#xff1a; 对于数组中的每个元素&#xff1a; 如果是运算符&#xff0c;从栈中弹出两个操作数&#xff0c;并根据运算符进行相应的运算&#xff0c;然后将结果压…