乐趣区

关于后端:Elasticsearch-向量搜索

Elasticsearch 向量搜寻

本文将会介绍 Elasticsearch 向量搜寻的两种形式。

向量搜寻

提到向量搜寻,我想你肯定想晓得:

  1. 向量搜寻是什么?
  2. 向量搜寻的利用场景有哪些?
  3. 向量搜寻与全文搜寻有何不同?

ES 的全文搜寻简而言之就是将文本进行分词,而后基于词通过 BM25 算法计算相关性得分,从而找到与搜寻语句类似的文本,其本质上是一种 term-based(基于词)的搜寻。

全文搜寻的理论应用曾经十分宽泛,核心技术也十分成熟。然而,除了文本内容之外,现实生活中还有十分多其它的数据模式,例如:图片、音频、视频等等,咱们能不能也对这些数据进行搜寻呢?

答案是 Yes !

随着机器学习和人工智能等技术的倒退, 万物皆可 Embedding。换句话说就是,咱们能够对文本、图片、音频、视频等等所有数据通过 Embedding 相干技术将其转换成特征向量,而一旦向量有了,向量搜寻的需要随之也越发强烈,向量搜寻的利用场景也变得一马平川、充斥想象力。

ES 向量搜寻阐明

ES 向量搜寻目前有两种形式:

  • script_score
  • _knn_search

script_score 准确搜寻

ES 7.6 版本对新增的字段类型 dense_vector 确认了稳定性保障,这个字段类型就是用来示意向量数据的。

数据建模示例:

PUT my-index
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 128
      },
      "my_text" : {"type" : "keyword"}
    }
  }
}

如上图所示,咱们在索引中建设了一个 dims 维度为 128 的向量数据字段。

script_score 搜寻示例:

{
  "script_score": {"query": {"match_all": {}},
    "script": {"source": "cosineSimilarity(params.query_vector,'my_vector') + 1.0",
      "params": {"query_vector": query_vector}
    }
  }
}

上图所示的含意是应用 ES 7.3 版本之后内置的 cosineSimilarity 余弦类似度函数计算向量之间的类似度得分。

须要留神的是,script_score 这种搜寻形式是先执行 query,而后对匹配的文档再进行向量类似度算分,其隐含的含意是:

  • 数据建模时向量字段能够与其它字段类型一起应用,也就是反对混合查问(先进行全文搜寻,再基于搜寻后果进行向量搜寻)。
  • script_score 是一种暴力计算,数据集越大,性能损耗就越大。

_knn_search 搜寻

因为 script_score 的性能问题,ES 在 8.0 版本引入了一种新的向量搜寻办法 _knn_search(目前处于试验性功能)。

所谓的 _knn_search 其实就是一种 approximate nearest neighbor search (ANN) 即 近似最近邻搜寻 。这种搜寻形式在就义肯定准确性的状况下优先谋求搜寻性能。

为了应用 _knn_search 搜寻,在数据建模时有所不同。

示例:

PUT my-index-knn
{
  "mappings": {
    "properties": {
      "my_vector": {
        "type": "dense_vector",
        "dims": 128,
        "index": true,
        "similarity": "dot_product"
      }
    }
  }
}

如上所示,咱们必须额定指定:

  • index 为 true。
  • similarity 指定向量类似度算法,能够是 l2_normdot_productcosine 其中之一。

额定指定 index 为 true 是因为,为了实现 _knn_search,ES 必须在底层构建一个新的数据结构(目前应用的是 HNSW graph)。

_knn_search 搜寻示例:

GET my-index-knn/_knn_search
{
  "knn": {
    "field": "my_vector",
    "query_vector": [0.3, 0.1, 1.2, ...],
    "k": 10,
    "num_candidates": 100
  },
  "_source": ["name", "date"]
}

应用 _knn_search 搜寻的长处就是搜寻速度十分快,毛病就是精确度不是百分百,同时无奈与 Query DSL 一起应用,即无奈进行混合搜寻。

参考文档

  • text-similarity-search-with-vectors-in-elasticsearch
  • dense-vector
  • knn-search
  • introducing-approximate-nearest-neighbor-search-in-elasticsearch
退出移动版