向量字段类型
> 文档中心 > 文档中心 > INFINI Easysearch > 功能手册 > 文档建模 > 字段类型 > 向量字段类型

k-NN 向量字段类型 #

关于向量 #

在索引文档和运行查询时都需要指定向量类型。在这两种情况下,您都使用相同的 JSON 结构来定义向量类型。每个向量类型还有一个简写形式,这在使用不支持嵌套文档的工具时会很方便。以下示例展示了如何在索引向量时指定它们。

knn_dense_float_vector 密集向量类型 #

假设您已经定义了一个映射,其中 my_vec 的类型为 knn_dense_float_vector。

POST /my-index/_doc
{
    "my_vec": {
        "values": [0.1, 0.2, 0.3, ...]    # 1
    }
}
POST /my-index/_doc
{
    "my_vec": [0.1, 0.2, 0.3, ...]        # 2
}

说明 #

1 向量中所有浮点值的 JSON 列表。长度应与映射中的dims匹配。 2 #1 的简写形式。

knn_sparse_bool_vector 稀疏向量类型 #

假设您已经定义了一个映射,其中 my_vec 的类型为 knn_sparse_bool_vector。

POST /my-index/_doc
{
    "my_vec": {
       "true_indices": [1, 3, 5, ...],   # 1
       "total_indices": 100,             # 2
    }
}
POST /my-index/_doc
{
    "my_vec": [[1, 3, 5, ...], 100]      # 3
}

说明 #

1 向量中为 true 的索引的 JSON 列表。 2 索引的向量总数。这应该与映射中的dims匹配。 3 #1 和 #2 的简写形式。一个包含两个项目的列表,第一个项目是 true_indices,第二个是 total_indices

映射 #

在索引向量数据之前,您需要先定义一个映射,指定向量数据类型、索引模型和模型参数。这决定了索引向量支持哪些查询。

基本结构 #

基本映射结构如下:

PUT /my-index/_mapping
{
  "properties": {                               # 1
    "my_vec": {                                 # 2 
      "type": "knn_sparse_bool_vector",         # 3
      "knn": {                            # 4
        "dims": 100,                            # 5
        "model": "exact",                       # 6
        ...                                     # 7
      }
    }
  }
}

说明 #

1 文档字段的字典。与 PUT Mapping API 相同。 2 向量的字段名称。 3 要存储的向量类型。 4 knn 的设置。 5 向量的维度。存储在此字段 my_vec 中的所有向量必须具有相同的维度。 6 模型类型。这和模型参数将决定您可以运行什么样的搜索。请参见下面的模型部分。 7 额外的模型参数。请参见下面的模型部分。

knn_sparse_bool_vector 数据类型 #

这种类型针对每个索引为 truefalse 的向量进行了优化,大部分的情况为 false。例如,您可以表示文档的词袋编码,其中每个索引对应词汇表中的一个词,而任何单个文档只包含所有词的很小一部分。在内部,Knn 通过只存储 true 的数据来节省空间。

PUT /my-index/_mapping
{
    "properties": {
        "my_vec": {
            "type": "knn_sparse_bool_vector",        # 1
            "knn": {
                "dims": 25000,                       # 2
                ...                                  # 3
            }
        }
    }
}

说明 #

1 类型名称。 2 向量的维度。 3 额外的模型参数。请参见下面的模型部分。

knn_dense_float_vector 数据类型 #

这种类型针对每个向量都是浮点数、所有索引都有值且维度通常不超过约 1000 的向量进行了优化。例如,您可以存储词嵌入或图像向量。在内部,Knn 使用 Java Float 类型来存储值。

PUT /my-index/_mapping
{
    "properties": {
        "my_vec": {
            "type": "knn_dense_float_vector",        # 1
            "knn": {
                "dims": 100,                         # 2
                ...                                  # 3
            }
        }
    }
}

说明 #

1 类型名称。 2 向量的维度。不应超过几千。如果超过,请考虑进行某种维度降低。 3 额外的模型参数。请参见下面的模型部分。

特定模型映射 #

特定模型映射允许您运行特定模型的搜索。这些搜索不利用任何索引结构,运行时间复杂度为 O(n^2),其中 n 是文档总数。

使用此配置时,您不需要提供任何 "model": "..." 值或任何模型参数。

PUT /my-index/_mapping
{
    "properties": {
        "my_vec": {
            "type": "knn_(dense_float | sparse_bool)_vector",        # 1
            "knn": {
                "dims": 100,                                         # 2
            }
        }
    }
}

说明 #

1 向量数据类型。支持 dense float 和 sparse bool 两种类型 2 向量维度。

Jaccard LSH 映射 #

使用 Minhash 算法对稀疏布尔向量进行哈希和存储,以支持近似 Jaccard 相似度查询。

该实现受到 《Mining Massive Datasets》第 3 章、Spark MinHash 实现、 tdebatty/java-LSH Github 项目和 Minhash for Dummies 博客文章的影响。

PUT /my-index/_mapping
{
    "properties": {
        "my_vec": {
            "type": "knn_sparse_bool_vector",       # 1
            "knn": {
                "dims": 25000,                      # 2
                "model": "lsh",                     # 3
                "similarity": "jaccard",            # 4
                "L": 99,                            # 5
                "k": 1                              # 6
            }
        }
    }
}

说明 #

1 向量数据类型。必须是稀疏布尔向量。 2 向量维度。 3 模型类型。 4 相似度度量。 5 哈希表的数量。通常增加这个值会提高召回率。 6 组合形成单个哈希值的哈希函数数量。通常,增加这个值会提高精确度。

汉明 LSH 映射 #

使用 位采样算法对稀疏布尔向量进行哈希和存储,以支持近似汉明相似度查询。

与标准位采样方法的唯一区别是它采样并组合 k 个位来形成单个哈希值。例如,如果设置 L = 100k = 3,它会从向量中采样 100 * 3 = 300 个位,并将每 3 个位连接起来形成每个哈希值,总共生成 100 个哈希值。

PUT /my-index/_mapping
{
    "properties": {
        "my_vec": {
            "type": "knn_sparse_bool_vector",       # 1
            "knn": {
                "dims": 25000,                      # 2
                "model": "lsh",                     # 3
                "similarity": "hamming",            # 4
                "L": 99,                            # 5
                "k": 2                              # 6
            }
        }
    }
}

说明 #

1 向量数据类型。必须是稀疏布尔向量。 2 向量维度。 3 模型类型。 4 相似度度量。 5 哈希表的数量。通常增加这个值会提高召回率。 6 组合形成单个哈希值的哈希函数数量。通常增加这个值会提高精确度。

余弦 LSH 映射 #

使用 随机投影算法对密集浮点向量进行哈希和存储,以支持近似余弦相似度查询。

参考 Mining Massive Datasets第三章

PUT /my-index/_mapping
{
    "properties": {
        "my_vec": {
            "type": "knn_dense_float_vector",       # 1
            "knn": {
                "dims": 100,                        # 2
                "model": "lsh",                     # 3
                "similarity": "cosine",             # 4
                "L": 99,                            # 5
                "k": 1                              # 6
            }
        }
    }
}

说明 #

1 向量数据类型。必须是密集浮点向量。 2 向量维度。 3 模型类型。 4 相似度度量。 5 哈希表的数量。通常增加这个值会提高召回率。 6 组合形成单个哈希值的哈希函数数量。通常,增加这个值会提高精确度。

L2 LSH 映射 #

使用 稳定分布方法对密集浮点向量进行哈希和存储,以支持近似 L2(欧几里得)相似度查询。

参考 Mining Massive Datasets第三章

PUT /my-index/_mapping
{
    "properties": {
        "my_vec": {
            "type": "knn_dense_float_vector",       # 1
            "knn": {
                "dims": 100,                        # 2
                "model": "lsh",                     # 3
                "similarity": "l2",                 # 4
                "L": 99,                            # 5
                "k": 1,                             # 6
                "w": 3                              # 7
            }
        }
    }
}

说明 #

1 向量数据类型。必须是密集浮点向量。 2 向量维度。 3 模型类型。 4 相似度度量。 5 哈希表的数量。通常增加这个值会提高召回率。 6 组合形成单个哈希值的哈希函数数量。通常增加这个值会提高精确度。 7 整数桶宽度。这决定了两个向量在投影到第三个公共向量上时必须多么接近,才能共享一个哈希值。典型值是低位整数。

排列 LSH 映射 #

使用 Amato 等人在 《Large-Scale Image Retrieval with Elasticsearch》中描述的模型。

该模型通过向量中绝对值最大的 k 个索引(向量中的位置)来描述向量。直觉是,每个索引对应于某个潜在概念,绝对值高的索引比绝对值低的索引携带更多关于其各自概念的信息。该方法的研究主要集中在余弦相似度上,尽管实现也支持 L1 和 L2。

例子 #

向量 [10, -2, 0, 99, 0.1, -8, 42, -13, 6, 0.1]k = 4 的索引为 [4, 7, -8, 1]。索引是 1 索引的,负值的索引被否定(因此 -8)。索引可以根据其排名可选地重复。在本例中,索引将被重复 [4, 4, 4, 4, 7, 7, 7, -8, -8, 1]。索引 4 具有最高的绝对值,因此它被重复 k - 0 = 4 次。索引 7 具有第二高的绝对值,因此它被重复 k - 1 = 3 次,依此类推。搜索算法将得分计算为存储向量表示和查询向量表示的交集的大小。因此,对于表示为 [2, 2, 2, 2, 7, 7, 7, 4, 4, 5] 的查询向量,交集为 [7, 7, 7, 4, 4],得分为 5。在一些实验中,重复实际上降低了召回率,因此建议您尝试使用和不使用重复。

PUT /my-index/_mapping
{
    "properties": {
        "my_vec": {
            "type": "knn_dense_float_vector",       # 1
            "knn": {
                "dims": 100,                        # 2
                "model": "permutation_lsh",         # 3
                "k": 10,                            # 4
                "repeating": true                   # 5
            }
        }
    }
}

说明 #

1 向量数据类型。必须是密集浮点向量。 2 向量维度。 3 模型类型。 4 选择的顶部索引数量。 5 是否根据其排名重复索引。请参见上面的重复注释。