6.milvus搜索search

milvus 版本2.4之后支持多向量搜索,但是我使用的是v2.3.1也是支持多向量搜索的。

两种类型的搜索

单向量搜索,collection中只有一个向量字段,使用search()方法。

多向量搜索,collection中有两个和多个向量字段,使用hybrid_search()方法。执行多个近似最近邻ANN搜索请求,合并结果,重新排序,返回最相关的匹配项。

单向量搜索

 

import random

from pymilvus import (
    connections,
    Collection
)

dim = 128

if __name__ == '__main__':
    connections.connect(alias="default", host="192.168.171.130", port='19530', user='', password='')

    collection_name = 'first_milvus'
    coll = Collection(collection_name)

    search_param = {
        'metric_type': 'COSINE',
        'params': {'ef': 40}  # 注意:ef的值要大于等于limit的值
    }
    search_data = [random.random() for _ in range(dim)]
    result = coll.search(
        data=[search_data],
        anns_field="embeddings",
        param=search_param,
        limit=5, # 对应attu中TopK5
        output_fields=['pk', 'embeddings']
    )
    print(result)

注意:metric_type如果为L2, 最佳匹配的score是0。如果为COSINE,最佳匹配的score是0.9999999403953552,也就说值越大越匹配。

多向量搜索

import random

from pymilvus import (
    connections,
    Collection
)

dim = 128

if __name__ == '__main__':
    connections.connect(alias="default", host="192.168.171.130", port='19530', user='', password='')

    collection_name = 'first_milvus'
    coll = Collection(collection_name)

    search_param = {
        'metric_type': 'COSINE',
        'params': {'ef': 40}  # 注意:ef的值要大于等于limit的值
    }
    # 多向量查询
    search_data = [[random.random() for _ in range(dim)], [random.random() for _ in range(dim)]]
    result = coll.search(
        data=search_data,
        anns_field="embeddings",
        param=search_param,
        limit=5,  # 对应attu中TopK5
        output_fields=['pk']
    )
    print(result)

返回的是一个也是一个数组,为每个查询向量返回一个单独的结果集。

分区搜索

创建一个collection,它的默认分区是_default

新建建其他分区 blue, red

向分区插入数据

代码实现

import uuid

import numpy as np
from pymilvus import (
    connections,
    FieldSchema,
    CollectionSchema,
    DataType,
    Collection
)

colletion_name = "xkj_milvus"
host = "192.168.171.130"
port = 19530
username = ""
password = ""
num_entities, dim = 3000, 3


def generate_uuid(number_of_uuids):
    uuids = [str(uuid.uuid4()) for _ in range(number_of_uuids)]
    return uuids
# 建立连接
connections.connect("default", host=host, port=port, user=username, password=password)
# 定义字段
field = [
    FieldSchema(name="pk", dtype=DataType.INT64, is_primary=True, auto_id=False),
    FieldSchema(name="random", dtype=DataType.DOUBLE),
    FieldSchema(name="comment", dtype=DataType.VARCHAR, max_length=200),
    FieldSchema(name="embeddings", dtype=DataType.FLOAT_VECTOR, dim=dim)
]
# 创建schema
schema = CollectionSchema(field, "xkj_milvus is the best demo")
# 创建collection
coll = Collection(colletion_name, schema, consistency_level="Bounded", shards_num=1)
# 创建分区blue,red
coll.create_partition(partition_name="blue")
coll.create_partition(partition_name="red")

# 插入数据
# seed=19530 设置了随机数生成器的种子,确保每次运行代码时生成的随机数序列是相同的(可重复性)。
rng = np.random.default_rng(seed=19530)
entities = [
    # 生成一个从 0 到 num_entities - 1 的整数列表
    [i for i in range(num_entities)],
    # 随机数生成器 rng 生成 num_entities 个随机浮点数,范围在 [0, 1) 之间
    # tolist() 将 NumPy 数组转换为 Python 列表
    # 如果 num_entities = 3,可能生成 [0.123, 0.456, 0.789]
    rng.random(num_entities).tolist(),
    # 生成一个包含 num_entities 个 UUID 字符串的列表, 列表可能用于为每个实体分配一个全局唯一的标识符
    generate_uuid(num_entities),
    # 使用随机数生成器 rng 生成一个形状为 (num_entities, dim) 的二维 NumPy 数组
    # num_entities表示二维数组中有几个数组,dim表示第二层数组里面有几个元素
    rng.random((num_entities, dim)),
]

coll.insert(data=entities, partition_name="blue")

entities0 = [
    # 生成一个从 0 到 num_entities - 1 的整数列表
    [i+3000 for i in range(num_entities)],
    # 随机数生成器 rng 生成 num_entities 个随机浮点数,范围在 [0, 1) 之间
    # tolist() 将 NumPy 数组转换为 Python 列表
    # 如果 num_entities = 3,可能生成 [0.123, 0.456, 0.789]
    rng.random(num_entities).tolist(),
    # 生成一个包含 num_entities 个 UUID 字符串的列表, 列表可能用于为每个实体分配一个全局唯一的标识符
    generate_uuid(num_entities),
    # 使用随机数生成器 rng 生成一个形状为 (num_entities, dim) 的二维 NumPy 数组
    # num_entities表示二维数组中有几个数组,dim表示第二层数组里面有几个元素
    rng.random((num_entities, dim)),
]
coll.insert(data=entities, partition_name="red")
# 刷新
coll.flush()

# 创建索引
index_params = {
    "index_type": "HNSW",
    "metric_type": "L2",
    "params": {
        "M": 16,
        "efConstruction": 40
    }
}
coll.create_index(
  field_name="embeddings",
  index_params=index_params,
  index_name="idx_em"
)
# 加载到内存
coll.load()
print("done")


指定分区进行搜索

import random

from pymilvus import (
    connections,
    Collection
)

dim = 128

if __name__ == '__main__':
    connections.connect(alias="default", host="192.168.171.130", port='19530', user='', password='')

    collection_name = 'xkj_milvus'
    coll = Collection(collection_name)

    search_param = {
        'metric_type': 'L2',
        'params': {'ef': 40}  # 注意:ef的值要大于等于limit的值
    }
    search_data = [[0.20963513851165771, 0.3974665701389313, 0.12019053101539612]]
    result = coll.search(
        data=search_data,
        anns_field="embeddings",
        param=search_param,
        limit=5,  # 对应attu中TopK5
        output_fields=['pk'],
        partition_names=["blue"]
        # expr='',
        # consistency_level="Eventually"
    )
    print(result)
<think>好的,我现在需要回答用户关于Milvus.search支持的相似度计算方法的问题。首先,我需要回顾一下Milvus的文档和相关引用内容,确保信息的准确性。 根据用户提供的引用,引用[1]提到向量相似度计算的核心方法包括欧氏距离、余弦相似度和内积。这可能直接回答了用户的问题。此外,引用[3]提到了nprobe参数影响搜索精度和速度,虽然与相似度计算方法无关,但说明Milvus搜索时有参数调整的选项。 接下来,我需要确认Milvus官方文档中支持的相似度计算方法。通常,Milvus支持多种距离度量,比如欧氏距离(L2)、内积(IP)、余弦相似度(通过归一化后的内积实现)、曼哈顿距离(L1)、杰卡德距离、汉明距离等。不过,用户提供的引用中没有提到所有,但引用[1]提到了欧氏距离、余弦和内积,这可能需要作为主要回答点,同时补充其他可能的方法。 需要注意,Milvus的不同版本可能支持不同的距离度量,但根据常见的知识,L2、IP和余弦是主要支持的。此外,余弦相似度在Milvus中通常通过归一化后的内积来计算,所以用户需要确保向量已经归一化,或者使用内积并手动处理。 另外,引用[2]提到Milvus提供了详细的文档和示例代码,因此建议用户查阅最新文档以获取准确信息。同时,引用[4]中的搜索参数设置可能影响相似度计算的效果,但方法本身是参数配置的一部分。 最后,总结Milvus.search支持的相似度计算方法应包括L2、IP、余弦、Jaccard、Hamming等,但需要根据不同的数据类型(浮点型或二进制)选择合适的度量方式。同时,正确设置索引类型和参数(如nprobe)也是优化搜索性能的关键。</think>Milvus.search 支持的相似度计算方法主要依赖于向量索引类型和数据格式,以下是具体支持的度量方式及使用要点: ### 一、浮点型向量常用方法 1. **欧氏距离 (L2)** - 计算向量间几何距离:$d = \sqrt{\sum_{i=1}^n (x_i - y_i)^2}$ - 适用场景:空间距离敏感的检索任务[^1] - 索引类型:`IVF_FLAT`, `HNSW` 等 2. **内积 (IP)** - 计算向量点积:$s = \sum_{i=1}^n x_i y_i$ - 需注意:使用前建议对向量归一化,否则结果可能受向量模长影响 - 索引类型:`IVF_PQ`, `GPU_IVF_PQ` 等 3. **余弦相似度** - 通过归一化后的内积实现:$\cos\theta = \frac{\sum x_i y_i}{\|x\|\|y\|}$ - 实际使用需先对向量做L2归一化,再使用IP计算 ### 二、二进制向量专用方法 1. **汉明距离 (Hamming)** - 计算二进制位差异数量 - 适用二进制编码数据(如哈希指纹) 2. **杰卡德距离 (Jaccard)** - 计算集合相似度:$J = 1 - \frac{|A \cap B|}{|A \cup B|}$ - 常用于文本指纹匹配 ### 三、配置方法示例 ```python # 在创建集合时指定距离度量 from pymilvus import CollectionSchema, FieldSchema, DataType dim = 128 id_field = FieldSchema(name="id", dtype=DataType.INT64, is_primary=True) vector_field = FieldSchema(name="vector", dtype=DataType.FLOAT_VECTOR, dim=dim) schema = CollectionSchema(fields=[id_field, vector_field], description="Test collection", params={"metric_type": "IP"}) # 可选L2/IP/COSINE等 # 搜索时指定参数 search_params = {"metric_type": "IP", "params": {"nprobe": 10}} results = collection.search(vectors, "vector", search_params, limit=5) ``` ### 四、选择建议 | 度量方式 | 数据特征 | 典型应用场景 | |----------|----------------------------|----------------------| | L2 | 需要精确几何距离 | 图像检索、物体检测 | | IP/COSINE| 方向敏感的高维稀疏数据 | 文本语义匹配、推荐系统 | | Hamming | 二进制编码数据 | 指纹去重、哈希检索 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卷土重来…

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值