Link Search Menu Expand Document Documentation Menu

Painless 脚本扩展

借助 Painless 脚本扩展,您可以直接在 Painless 脚本中使用 k-近邻 (k-NN) 距离函数,对 knn_vector 字段执行操作。Painless 为每个上下文设置了严格的允许函数和类列表,以确保其脚本的安全。OpenSearch 为 k-NN 评分脚本中使用的几个距离函数添加了 Painless 脚本扩展,因此您可以使用它们来自定义 k-NN 工作负载。

k-NN Painless 脚本函数入门

要使用 k-NN Painless 脚本函数,首先创建一个带有 knn_vector 字段的索引,如向量评分脚本入门中所述。创建索引并摄入一些数据后,您就可以使用 Painless 扩展了

GET my-knn-index-2/_search
{
  "size": 2,
  "query": {
    "script_score": {
      "query": {
        "bool": {
          "filter": {
            "term": {
              "color": "BLUE"
            }
          }
        }
      },
      "script": {
        "source": "1.0 + cosineSimilarity(params.query_value, doc[params.field])",
        "params": {
          "field": "my_vector",
          "query_value": [9.9, 9.9]
        }
      }
    }
  }
}

field 需要映射到 knn_vector 字段,并且 query_value 必须是一个与 field 具有相同维度的浮点数组。

函数类型

下表描述了 OpenSearch 提供的 Painless 函数。

函数名称 函数签名 描述
l2Squared float l2Squared (float[] queryVector, doc['vector field']) 此函数计算给定查询向量和文档向量之间 L2 距离(欧几里得距离)的平方。较短的距离表示更相关的文档,因此此示例反转了 l2Squared 函数的返回值。如果文档向量与查询向量匹配,结果为 0,因此此示例还在距离上加 1,以避免除以零错误。
l1Norm float l1Norm (float[] queryVector, doc['vector field']) 此函数计算给定查询向量和文档向量之间 L1 范数距离(曼哈顿距离)。
cosineSimilarity float cosineSimilarity (float[] queryVector, doc['vector field']) 余弦相似度是查询向量和文档向量的内积,均归一化为长度 1。如果查询向量的幅值在整个查询过程中没有变化,您可以传递查询向量的幅值以提高性能,而不是为每个过滤文档重复计算幅值
float cosineSimilarity (float[] queryVector, doc['vector field'], float normQueryVector)
通常,余弦相似度的范围是 [-1, 1]。然而,在信息检索的情况下,两个文档的余弦相似度范围是 01,因为 tf-idf 统计量不能为负。因此,OpenSearch 添加了 1.0,以便始终产生正的余弦相似度分数。
hamming float hamming (float[] queryVector, doc['vector field']) 此函数计算给定查询向量和文档向量之间的汉明距离。汉明距离是对应元素不同的位置数量。较短的距离表示更相关的文档,因此此示例反转了汉明距离的返回值。

OpenSearch 2.16 及更高版本支持二进制向量的 hamming 空间类型。有关更多信息,请参阅二进制 k-NN 向量

约束

  1. 如果文档的 knn_vector 字段与查询的维度不同,该函数将抛出 IllegalArgumentException

  2. 如果向量字段没有值,该函数将抛出 IllegalStateException

    您可以通过首先检查文档的字段中是否包含值来避免这种情况。

    "source": "doc[params.field].size() == 0 ? 0 : 1 / (1 + l2Squared(params.query_value, doc[params.field]))",
    

    由于分数只能是正数,此脚本将向量字段文档的排名高于没有向量字段的文档。

使用余弦相似度时,将零向量([0, 0, ...])作为输入是不合法的。这是因为此类向量的幅值为 0,这会在相应的公式中引发 除以 0 异常。包含零向量的请求将被拒绝,并抛出相应的异常。

剩余 350 字符

有问题?

想要贡献?