密集向量字段类型编辑

dense_vector 字段类型存储数值的密集向量。密集向量字段主要用于 k 近邻 (kNN) 搜索

dense_vector 类型不支持聚合或排序。

您可以添加一个 dense_vector 字段,作为基于 element_type 的数值数组,默认情况下为 float

response = client.indices.create(
  index: 'my-index',
  body: {
    mappings: {
      properties: {
        my_vector: {
          type: 'dense_vector',
          dims: 3
        },
        my_text: {
          type: 'keyword'
        }
      }
    }
  }
)
puts response

response = client.index(
  index: 'my-index',
  id: 1,
  body: {
    my_text: 'text1',
    my_vector: [
      0.5,
      10,
      6
    ]
  }
)
puts response

response = client.index(
  index: 'my-index',
  id: 2,
  body: {
    my_text: 'text2',
    my_vector: [
      -0.5,
      10,
      10
    ]
  }
)
puts response
PUT my-index
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 3
      },
      "my_text" : {
        "type" : "keyword"
      }
    }
  }
}

PUT my-index/_doc/1
{
  "my_text" : "text1",
  "my_vector" : [0.5, 10, 6]
}

PUT my-index/_doc/2
{
  "my_text" : "text2",
  "my_vector" : [-0.5, 10, 10]
}

与大多数其他数据类型不同,密集向量始终是单值的。无法在一个 dense_vector 字段中存储多个值。

为 kNN 搜索索引向量编辑

k 近邻 (kNN) 搜索根据相似度指标找到与查询向量最接近的 k 个向量。

密集向量字段可用于在 script_score 查询 中对文档进行排名。这使您可以通过扫描所有文档并根据相似度对它们进行排名来执行暴力 kNN 搜索。

在许多情况下,暴力 kNN 搜索效率不够高。为此,dense_vector 类型支持将向量索引到专门的数据结构中,以通过搜索 API 中的 knn 选项 支持快速 kNN 检索。

大小在 128 到 4096 之间的浮点元素的未映射数组字段将被动态映射为 dense_vector,默认相似度为 cosine。您可以通过将字段显式映射为具有所需相似度的 dense_vector 来覆盖默认相似度。

密集向量字段默认情况下启用索引,并作为 int8_hnsw 索引。启用索引后,您可以定义在 kNN 搜索中使用的向量相似度。

response = client.indices.create(
  index: 'my-index-2',
  body: {
    mappings: {
      properties: {
        my_vector: {
          type: 'dense_vector',
          dims: 3,
          similarity: 'dot_product'
        }
      }
    }
  }
)
puts response
PUT my-index-2
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 3,
        "similarity": "dot_product"
      }
    }
  }
}

为近似 kNN 搜索索引向量是一个昂贵的过程。为包含启用 index 的向量字段的文档进行数据摄取可能需要大量时间。请参阅 k 近邻 (kNN) 搜索,详细了解内存需求。

您可以通过将 index 参数设置为 false 来禁用索引。

response = client.indices.create(
  index: 'my-index-2',
  body: {
    mappings: {
      properties: {
        my_vector: {
          type: 'dense_vector',
          dims: 3,
          index: false
        }
      }
    }
  }
)
puts response
PUT my-index-2
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 3,
        "index": false
      }
    }
  }
}

Elasticsearch 使用 HNSW 算法 来支持高效的 kNN 搜索。与大多数 kNN 算法一样,HNSW 是一种近似方法,它以牺牲结果准确性为代价来提高速度。

自动量化用于 kNN 搜索的向量编辑

dense_vector 类型支持量化,以减少 搜索 float 向量时所需的内存占用。目前,唯一支持的量化方法是 int8,并且提供的向量 element_type 必须为 float。要使用量化索引,您可以将索引类型设置为 int8_hnsw。在索引 float 向量时,当前默认索引类型为 int8_hnsw

使用 int8_hnsw 索引时,每个 float 向量的维度都将量化为 1 字节整数。这可以将内存占用减少多达 75%,但会以牺牲一些准确性为代价。但是,由于存储量化向量和原始向量的开销,磁盘使用量可能会增加 25%。

response = client.indices.create(
  index: 'my-byte-quantized-index',
  body: {
    mappings: {
      properties: {
        my_vector: {
          type: 'dense_vector',
          dims: 3,
          index: true,
          index_options: {
            type: 'int8_hnsw'
          }
        }
      }
    }
  }
)
puts response
PUT my-byte-quantized-index
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 3,
        "index": true,
        "index_options": {
          "type": "int8_hnsw"
        }
      }
    }
  }
}

密集向量字段的参数编辑

接受以下映射参数。

element_type
(可选,字符串) 用于编码向量的數據類型。支持的数据类型为 float(默认)和 bytefloat 为每个维度索引一个 4 字节浮点值。 byte 为每个维度索引一个 1 字节整数值。使用 byte 可以导致索引大小大幅减小,但会以降低精度为代价。使用 byte 的向量要求维度具有 -128 到 127(含)之间的整数值,用于索引和搜索。
dims
(可选,整数) 向量维度的数量。不能超过 4096。如果未指定 dims,则将其设置为添加到字段的第一个向量的长度。
index
(可选,布尔值) 如果为 true,则可以使用 kNN 搜索 API 搜索此字段。默认值为 true
similarity

(可选*,字符串) 在 kNN 搜索中使用的向量相似度指标。文档根据其向量字段与查询向量的相似度进行排名。每个文档的 _score 将从相似度中得出,以确保分数为正,并且分数越大,排名越高。默认值为 cosine

* 此参数只能在 indextrue 时指定。

similarity 的有效值
l2_norm
根据向量之间的 L2 距离(也称为欧几里得距离)计算相似度。文档 _score 计算为 1 / (1 + l2_norm(query, vector)^2)
dot_product

计算两个单位向量的点积。此选项提供了一种优化方法来执行余弦相似度。约束和计算的分数由 element_type 定义。

element_typefloat 时,所有向量都必须是单位长度,包括文档向量和查询向量。文档 _score 计算为 (1 + dot_product(query, vector)) / 2

element_typebyte 时,所有向量都必须具有相同的长度,包括文档向量和查询向量,否则结果将不准确。文档 _score 计算为 0.5 + (dot_product(query, vector) / (32768 * dims)),其中 dims 是每个向量的维度数。

cosine
计算余弦相似度。在索引过程中,Elasticsearch 会自动将具有 cosine 相似度的向量归一化为单位长度。这允许在内部使用 dot_product 来计算相似度,这更有效。原始的未归一化向量仍然可以通过脚本访问。文档 _score 计算为 (1 + cosine(query, vector)) / 2cosine 相似度不允许大小为零的向量,因为在这种情况下余弦未定义。
max_inner_product
计算两个向量的最大内积。这类似于 dot_product,但不需要向量进行归一化。这意味着每个向量的幅度会显著影响分数。文档 _score 会进行调整以防止出现负值。对于 max_inner_product< 0_score1 / (1 + -1 * max_inner_product(query, vector))。对于非负的 max_inner_product 结果,_score 计算为 max_inner_product(query, vector) + 1

虽然它们在概念上相关,但 similarity 参数与 text 字段 similarity 不同,并且接受一组不同的选项。

index_options

(可选*,对象) 一个可选部分,用于配置 kNN 索引算法。HNSW 算法有两个内部参数会影响数据结构的构建方式。可以调整这些参数以提高结果的准确性,但会以索引速度变慢为代价。

* 此参数只能在 indextrue 时指定。

index_options 的属性
type

(必需,字符串) 要使用的 kNN 算法类型。可以是以下任何一种

  • hnsw - 这利用了 HNSW 算法 来实现可扩展的近似 kNN 搜索。这支持所有 element_type 值。
  • int8_hnsw - 浮点向量的默认索引类型。这利用了 HNSW 算法 以及自动标量量化,以实现可扩展的近似 kNN 搜索,element_typefloat。这可以将内存占用减少 4 倍,但会以牺牲一些准确性为代价。请参阅 自动量化用于 kNN 搜索的向量
  • flat - 这利用了暴力搜索算法来实现精确的 kNN 搜索。这支持所有 element_type 值。
  • int8_flat - 这利用了暴力搜索算法以及自动标量量化。仅支持 element_typefloat 的情况。
m
(可选,整数) 每个节点将在 HNSW 图中连接到的邻居数量。默认值为 16。仅适用于 hnswint8_hnsw 索引类型。
ef_construction
(可选,整数) 在为每个新节点组装最近邻居列表时要跟踪的候选者数量。默认值为 100。仅适用于 hnswint8_hnsw 索引类型。
confidence_interval
(可选,浮点数) 仅适用于 int8_hnswint8_flat 索引类型。用于量化向量的置信区间,可以是介于 0.901.0(包括)之间的任何值。此值限制了计算量化阈值时使用的值。例如,值为 0.95 将仅使用中间 95% 的值来计算量化阈值(例如,最高和最低 2.5% 的值将被忽略)。默认为 1/(dims + 1)

合成 _source编辑

合成 _source 仅对 TSDB 索引(将 index.mode 设置为 time_series 的索引)普遍可用。对于其他索引,合成 _source 处于技术预览阶段。技术预览中的功能可能会在将来的版本中更改或删除。Elastic 将努力解决任何问题,但技术预览中的功能不受官方 GA 功能的支持 SLA 的约束。

dense_vector 字段支持 合成 _source