• 关于 Milvus
  • 开始使用
  • 概念
  • 用户指南
    • Collections
    • Schema与数据字段
    • 插入与删除
    • 索引
    • 搜索
    • 函数与模型推断
    • 存储优化
    • 快照
  • 数据导入
  • AI 工具
  • 管理指南
  • 工具
  • 集成
  • 教程
  • 常见问题解答
  • API Reference

MinHash 函数Compatible with Milvus 3.0.x

MinHash 函数将原始文本转换为二进制向量,这些向量可近似表示文档之间的雅卡德相似度。该函数通过文本分块和多种哈希函数,生成固定长度的签名向量,从而实现快速近似重复检测和大规模文档去重。

作为内置函数,MinHash 在 Milvus 内部运行,无需外部模型推理或预处理。您只需输入原始文本,Milvus 便会自动生成 MinHash 签名向量。

限制

  • 输出字段必须为BINARY_VECTOR ,且其维度需满足dim % 32 == 0 ,因为每个MinHash签名都是一个32位哈希值。

  • 二进制向量字段的dim 必须等于32 * num_hashes 。若不匹配,将引发错误。

  • 当使用MINHASH_LSH 索引与MinHash函数的输出时,mh_element_bit_width 必须设置为32

MinHash的工作原理

展开以查看其工作原理

MinHash是一种局部敏感哈希技术,用于估算集合之间的雅卡德相似度。在 Milvus 中,MinHash 函数遵循以下处理流程:您提供原始文本作为输入,Milvus 生成二进制向量作为输出——所有中间步骤均由系统内部处理。

整体工作流由文档摄入和查询处理共用的文本处理管道组成,随后是针对存储和检索阶段的特定操作。

Iaqkbfeh8oqggsx6nsocfosondo Iaqkbfeh8oqggsx6nsocfosondo

共享文本处理管道

无论是文档摄入还是查询处理,都会将原始文本经过相同的四阶段转换:

  1. 文本分析:文本由分析器处理(当token_level"word" 时),或直接使用(当token_level"char" 时)。词级分词会应用在输入字段上配置的分析器,将文本分割为术语——例如,"milvus is vector db" 将变为["milvus", "is", "vector", "db"]

  2. 分片:将分词结果拆分为大小为shingle_size 的重叠 n-gram(分片)。例如,在词级使用 3-gram 时,分词结果["information", "retrieval", "is", "a", "field"] 将被拆分为类似["information retrieval is", "retrieval is a", "is a field"] 的分片。

  3. MinHash签名生成:对瓦片集应用多个哈希函数(H1、H2、…、Hn,其中n =num_hashes )。 对于每个哈希函数,选取所有片段中的最小哈希值。这些最小值的 Collection 构成了 MinHash 签名——一种固定长度的表示形式,近似反映了原始文档的雅卡德相似度。

  4. 二进制向量编码:每个签名值是一个 32 位哈希值,完整的签名被打包到一个维度为32 * num_hashesBINARY_VECTOR 中。

文档摄入

在插入过程中,由共享管道生成的二进制向量会被存储在MINHASH_LSH 索引中。该索引维护着一个LSH(局部敏感哈希)表,将相似的签名分组到相同的桶中,从而在查询时能够快速检索候选结果。

查询处理

在搜索过程中,查询文本会经过相同的共享管道以生成二进制向量。该向量用于在MINHASH_LSH 索引中执行LSH查找,从而快速识别出可能相似的候选对。若未启用Jaccard精化,Milvus返回的LSH候选结果不会按估计的Jaccard相似度进行排序。 当启用雅卡德(Jaccard)精化时,Milvus 会利用存储的原始 MinHash 签名,根据估计的雅卡德相似度对候选结果进行排序,并返回前 K 个结果。

由于这两种路径共享相同的转换逻辑,内容高度重叠的两份文档会产生相似的 MinHash 签名。这使得该功能即使在文档的词序、格式或细微措辞存在差异时,也能有效查找近似重复文档。

开始之前

在使用 MinHash 功能之前,请规划您的 Collection Schema,确保包含以下内容:

  • 用于存储原始内容的文本字段

    您的Collection必须包含一个VARCHAR 字段来存储原始文本。该字段将作为MinHash函数的输入。

  • 文本字段的分析器(当使用词级分词时)

    如果 `token_level ` 设置为 `"word" `(默认值),则文本字段必须启用分析器。分析器定义了在分片处理之前如何对文本进行分词。默认情况下,Milvus 使用 `standard ` 分析器。若要配置其他分析器,请参阅《根据用例选择合适的分析器》。

  • 用于 MinHash 输出的二进制向量字段

    您的Collection必须包含一个BINARY_VECTOR 字段,用于存储由MinHash函数生成的二进制向量。该维度的值必须等于32 * num_hashes

步骤 1:创建包含 MinHash 函数的 Collection

要使用 MinHash 函数,请在创建 Collection 时对其进行定义。该函数将成为 Collection Schema 的部分,并在数据插入和搜索过程中自动应用。

定义Schema字段

您的Collection Schema必须包含至少三个字段:

  • 主字段:用于唯一标识Collection中的每个实体。

  • 文本字段VARCHAR ):用于存储原始文本文档。请将enable_analyzer=True 设置为启用,以便 Milvus 能对文本进行处理以生成 MinHash 签名。默认情况下,Milvus 使用standard 分析器进行文本分析。若要配置其他分析器,请参阅《根据用例选择合适的分析器》。

  • 二进制向量字段BINARY_VECTOR ):用于存储由 MinHash 函数自动生成的二进制向量。其维度必须与32 * num_hashes 相同。

from pymilvus import MilvusClient, DataType, Function, FunctionType

client = MilvusClient(uri="http://localhost:19530", token="root:Milvus")

schema = client.create_schema()

schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True, auto_id=True)
schema.add_field(field_name="document_content", datatype=DataType.VARCHAR, max_length=9000, enable_analyzer=True)
schema.add_field(field_name="binary_vector", datatype=DataType.BINARY_VECTOR, dim=8192)
// java
// nodejs
// go
# restful

定义 MinHash 函数

MinHash 函数将分析后的文本转换为二进制向量,这些向量可近似表示文档之间的雅卡德相似度。

定义该函数并将其添加到您的Schema中:

minhash_function = Function(
    name="minhash_function",
    input_field_names=["document_content"], # Name of the VARCHAR field containing raw text
    output_field_names=["binary_vector"], # Name of the BINARY_VECTOR field for generated signatures
    function_type=FunctionType.MINHASH,
    params={
        "num_hashes": 256, # Number of hash functions; produces dim = 32 * 256 = 8192
        "shingle_size": 3, # N-gram size for shingling
    }
)

schema.add_function(minhash_function)
// java
// nodejs
// go
# restful

配置选项

MinHash 函数的 `params ` 字典支持以下参数。所有参数名称均不区分大小写

参数

类型

默认值

描述

num_hashes

int

源自dim / 32

用于签名生成的哈希函数数量。输出二进制向量的维度等于32 * num_hashes 。数值越大,相似度估计的方差越小,但计算量也会增加。推荐值:256 (dim = 8192)。

shingle_size

int

3

用于分段处理的N-gram大小。词级:通常为1-3。字符级:通常为2-6。

hash_function

str

"xxhash"

要使用的哈希函数。选项:

  • "xxhash" (fast)

  • "sha1" (速度较慢,抗碰撞能力更强)。

token_level

str

"word"

分词级别。选项:

  • "word":使用字段的分析器进行分词,然后应用 n-gram 分段处理。

  • "char" /"character": 直接对原始字符应用 n-gram 分片(不使用分析器)。

    词级提供更强的语义和更高的效率,但依赖于特定语言的分词。字符级与语言无关,但会产生高维度的分片,且语义较弱。

seed

int

1234

用于初始化 MinHash 函数的随机种子。

配置索引

MinHash 二进制向量的推荐索引类型为MINHASH_LSH ,度量类型为MHJACCARD

index_params = client.prepare_index_params()

index_params.add_index(
    field_name="binary_vector",
    index_type="MINHASH_LSH",
    metric_type="MHJACCARD",
    params={
        "mh_lsh_band": 128,
        "mh_element_bit_width": 32,
        "with_raw_data": True,
    },
)
// java
// nodejs
// go
# restful

如果搜索将使用雅卡德(Jaccard)精化,请将with_raw_data 设置为True 。计算LSH查找返回的候选项的估计雅卡德相似度时,需要原始的MinHash签名。

创建Collection

使用上述定义的Schema和索引参数创建Collection:

client.create_collection(
    collection_name="dedup_collection",
    schema=schema,
    index_params=index_params,
)
// java
// nodejs
// go
# restful

步骤 2:插入文档

设置好 Collection 后,插入文本数据。您只需提供原始文本——MinHash 函数会自动为每份文档生成二进制向量。

client.insert(
    "dedup_collection",
    [
        {"document_content": "information retrieval is a field of study that helps users find relevant information in large datasets"},
        {"document_content": "information retrieval is a research field focused on helping users find relevant data in large collections"},
        {"document_content": "information retrieval is a field of research helping users search for relevant information in large datasets"},
    ],
)
// java
// nodejs
// go
# restful

步骤 3:使用 MinHash 进行搜索

插入数据后,通过提供原始文本查询来搜索近似重复的文档。Milvus 会自动将每个查询转换为 MinHash 二进制向量。启用 Jaccard 精炼功能,即可根据估计的 Jaccard 相似度对 LSH 候选结果进行排序。

search_params = {
    "metric_type": "MHJACCARD",
    "params": {
        "mh_search_with_jaccard": True,
        "refine_k": 3,
    },
}

results = client.search(
    collection_name="dedup_collection",
    data=["information retrieval is a research field focused on helping users find relevant data in large collections"],
    anns_field="binary_vector",
    limit=3,
    output_fields=["document_content"],
    search_params=search_params,
)

for hits in results:
    for hit in hits:
        print(f"ID: {hit['id']}, Distance: {hit['distance']}")
        print(f"Document: {hit['entity']['document_content']}")
// java
// nodejs
// go
# restful

mh_search_with_jaccard 设置为True 以启用Jaccard精化。refine_k 控制用于精化的候选集容量。Milvus默认使用max(refine_k, limit) 作为容量,但如果LSH查找返回的匹配结果较少,则可能精化较少的候选项。增加refine_k 可以提高结果质量,但会增加计算开销。

下一步

  • 全文搜索:使用 BM25 进行词汇相关性排序,而非近似重复检测。

  • 分析器概述:配置自定义分析器以进行文本分词。

  • MINHASH_LSH 索引:了解如何调整 LSH 参数以优化召回率和性能。