Milvus向量数据库基础用法及注意细节

1、Milvus数据类型与python对应的数据类型

Milvus

Python

DataType.INT64

numpy.int64

DataType.INT32

numpy.int32

DataType.INT16

numpy.int16

DataType.BOOL

Boolean

DataType.FLOAT

numpy.float32

DataType.DOUBLE

numpy.double

DataType.ARRAY

list

DataType.VARCHAR

str

DataType.JSON

dict

FLOAT_VECTOR(浮点数向量)

numpy.ndarray or list (元素为numpy.float)

2、python创建集合->构建索引->发布步骤

(1)连接向量数据库:

from pymilvus import connections,db
connections.connect("default",host="localhost",prot="19530")

(2)删除现有集合:

from pymilvus import utility
utility.drop_collection('ITEM_INFO')

(3)字段常用数据类型创建:

from pymilvus import FieldSchema, DataType
# 创建数据类型为INT64的主键,且主键ID自动递增
ID_col = FieldSchema(
    name="ID",
    dtype=DataType.INT64,
    is_primary=True,
    description='主键、序号',
    auto_id=True)
# 创建一个768维的浮点向量
vec_col = FieldSchema(
    name="itemVec",
    dtype=DataType.FLOAT_VECTOR,
    dim=768,
    description = '向量')
# 创建一个长度128维的字符串
name_col = FieldSchema(
    name = 'itemName',
    dtype = DataType.VARCHAR,
    max_length = 128,
    description = '商品名称')
# 创建double类型的浮点数
price_col = FieldSchema(
    name = 'itemPrice',
    dtype = DataType.DOUBLE,
    description = '价格')
# 创建json格式的字段
keywords_col = FieldSchema(
    name = 'keywords',
    dtype = DataType.JSON)

(4)创建集合

from pymilvus import CollectionSchema, Collection, connections
# 集合所包含的字段
schema = CollectionSchema(
  fields=[ID_col,vec_col,name_col,price_col,keywords_col],
  description="商品信息表",
  enable_dynamic_field=True
)
# 集合名称
collection_name = "GOODS_INFO"
# 构建集合后断开连接
collection = Collection(
    name=collection_name,
    schema=schema,
    using='default',
    shards_num=2
    )
connections.disconnect("default")

(5)构建索引

Milvus中构建索引的数据量最小为1024满足2的幂次方数据量不满1024时必须使用1024构建索引。

from pymilvus import Collection
# 连接集合
collection = Collection("GOODS_INFO")  
# 构建索引所需的参数
index_params = {
  "metric_type":"L2",
  "index_type":"IVF_FLAT",
  "params":{"nlist":1024}
}
# 在向量上构建索引
collection.create_index(
  field_name="itemVec", 
  index_params=index_params)

(6)发布集合

from pymilvus import Collection, utility, connections
# 连接集合
collection = Collection("GOODS_INFO")      
# 发布集合
collection.load()
# 检查集合上线状态
utility.load_state("GOODS_INFO")
# 断开与向量数据库的连接
connections.disconnect('default')

3、条件过滤

1、假设集合中有一字段A的数据类型为整型或浮点型,则可以

expr = 'A > 0 && A <= 10'

2、假设集合中有一字段A为任意数据类型,则可以

# a,b,c,d为任意数据类型,可与A相同或不同
expr = 'A in [a,b,c,d]'
expr = 'A not in [a,b,c,d]'

3、假设集合中有一字段A为字符类型,则可以 # 在条件过滤中字符串要添加引号确定

# 在条件过滤中字符串要添加引号确定
expr = "A == 'Hello World!'"

4、假设集合中有一字段A为字符类型,则可以

# 从A开头为123的向量中进行向量检索,目前milvus只支持字符前缀匹配,不支持'1%23'或'%123'
expr = "A like '123%'"

5、假设集合中有一字段A为json类型,则可以

# A = {"x": [1,2,3]}
expr = 'json_contains(A["x"], 1)' # ==> true
expr = 'json_contains(A["x"], "a")' # ==> false
    
# A = {"x": [[1,2,3], [4,5,6], [7,8,9]]}
expr = 'json_contains(A["x"], [1,2,3])' # ==> true
expr = 'json_contains(A["x"], [3,2,1])' # ==> false

# A = {"x": [1,2,3,4,5,7,8]}
expr = 'json_contains_all(A["x"], [1,2,8])' # ==> true
expr = 'json_contains_all(A["x"], [4,5,6])' # ==> false 6 is not exists

# A = {"x": [1,2,3,4,5,7,8]}
expr = 'json_contains_any(A["x"], [1,2,8])' # ==> true
expr = 'json_contains_any(A["x"], [4,5,6])' # ==> true
expr = 'json_contains_any(A["x"], [6,9])' # ==> false

6、假设集合中有一字段A为list类型,则可以

# 该方法为上述方法2、的逆方法
# A: [1,2,3]
expr = 'array_contains(A, 1)' # ==> true
expr = 'array_contains(A, "a")' # ==> false

# A: [1,2,3,4,5,7,8]
expr = 'array_contains_all(A, [1,2,8])' # ==> true
expr = 'array_contains_all(A, [4,5,6])' # ==> false 6 is not exists

# A: [1,2,3,4,5,7,8]
expr = 'array_contains_any(A, [1,2,8])' # ==> true
expr = 'array_contains_any(A, [4,5,6])' # ==> true
expr = 'array_contains_any(A, [6,9])' # ==> false

# A: [1,2,3,4,5,7,8]
expr = 'array_length(int_array) == 7' # ==> true

假设有一集合,集合当中包含V、A、B、C四个字段:

V:浮点向量

A:向量的字符表达形式

B:A的属性1

C:A的属性2

现有一查询向量S、过滤条件E1和过滤条件E2(E1、E2均为列表),集合需要返回S与V相似度最高,且B包含于E1、C包含于E2的字符名称A。如果采用上述1、2、3、4方法中较基础的数据类型存表会导致查询速度和代码复杂度都较高。假设E1 = [1,2,3],E2 = [4,5,6],则对于同一条向量,需要做3 x 3 = 9次过滤。若使用5、6方法中的数据类型存表则可以将过滤次数降为2次。

例如

# B和C为字符串类型
expr = '(1 in B && 4 in C) or (1 in B && 5 in C) or (1 in B && 6 in C) ...'

# B和C为keywords中的元素,keywords为json格式
expr = "json_contains_any(keywords['B'], E1) && json_contains_any(keywords['C'], E2)"

# B和C均为列表
expr = "array_contains_any(B, E1) && json_contains_any(C, E2)"

4、查询

from pymilvus import Collection, connections

# 连接数据库,连接集合,将集合数据上传至内存
connections.connect("default",host="localhost",prot="19530")
knowledge = Collection('GOODS_INFO', using='default')
knowledge.load()

# 查询参数
search_params = {
    "metric_type": "L2",
    "offset": 0,
    "ignore_growing": False,
    "params": {
        "nprobe": 10,
        # "radius": 10,  # 对于L2,返回距离在[5,10)之间的向量
        # "range_filter": 5.0  # 对于IP,返回相似度在(0.8,1]之间的向量
    }
}

# 进行向量查询
results = knowledge.search(
    data=query,				#带查询向量
    anns_field='itemVec',	#表中向量字段名称
    param=search_params,	#查询参数
    limit=5,				#返回数量
    expr=expr,				#过滤条件,expr = None或''时,默认为不使用条件过滤
    output_fields=['itemName', 'itemPrice', 'keywords']	#返回的字段名称)

# 断开数据库连接
connections.remove_connection('default')

5、参考资料

Create a Collection Milvus documentation

你可能感兴趣的:(milvus,数据库)