k-NN 查询 API

k-NN 查询 API #

先决条件 #

要运行 k-NN 搜索,必须安装 knn 插件,参考 插件安装

注意:从 1.11.1 版本起,创建 k-NN 索引时不再需要配置 index.knn 参数。

向量字段的映射参数、各索引模型和相似度函数的详细说明,请参阅 向量字段类型参考

查询语法 #

所有向量搜索都通过 knn_nearest_neighbors 查询完成:

GET /<index>/_search
{
  "query": {
    "knn_nearest_neighbors": {
      "field": "<vector_field>",
      "vec": { ... },
      "model": "<model>",
      "similarity": "<similarity>",
      "candidates": <n>
    }
  }
}

查询参数 #

参数类型必填说明
fieldString向量字段名称
vecObject查询向量,支持三种格式(见下方)
modelString索引模型:lshexactpermutation_lshsparse_indexed
similarityString相似度函数,必须与映射中的配置一致
candidatesInteger近似搜索的候选数量。仅用于 lsh/permutation_lsh/sparse_indexed 模型。越大越精准但越慢,推荐 size 的 5~10 倍
probesInteger仅用于 l2 相似度的 LSH 查询:探测数量

查询向量格式 #

1. 直接提供值(最常用) #

"vec": {
  "values": [0.12, -0.03, 0.88, 0.45, ...]
}

用于稠密浮点向量(knn_dense_float_vector),数组长度必须与映射中的 dims 一致。

2. 引用已索引向量 #

"vec": {
  "index": "my-vectors",
  "id": "doc-1",
  "field": "embedding"
}

用已存在文档的向量作为查询向量,避免在请求中传递完整向量。参数说明:

参数说明
index源文档所在的索引名
id源文档 ID
field源文档中的向量字段名

3. 稀疏布尔向量 #

"vec": {
  "values": [[0, 3, 5, 12, 88], 1000]
}

用于稀疏布尔向量(knn_sparse_bool_vector),格式为 [[true_indices], total_dims]


LSH 近似搜索 #

最常用的查询方式,通过局部敏感哈希实现高效近似最近邻搜索。

稠密浮点向量 + LSH #

以 GloVe 词向量为例,查找与 “bread” 最相似的词:

GET /glove-vectors/_search
{
  "size": 5,
  "_source": "word",
  "query": {
    "knn_nearest_neighbors": {
      "field": "my_vec",
      "vec": {
        "values": [-0.37436, -0.11959, -0.87609, -1.1217, 1.2788, 0.48323, ...]
      },
      "model": "lsh",
      "similarity": "cosine",
      "candidates": 50
    }
  }
}

响应示例 #

{
  "took": 214,
  "hits": {
    "total": { "value": 400, "relation": "eq" },
    "max_score": 2,
    "hits": [
      {
        "_index": "glove-vectors",
        "_id": "WYPvCYkBkPNAx5w6LJ6H",
        "_score": 2,
        "_source": { "word": "bread" }
      },
      {
        "_index": "glove-vectors",
        "_id": "PYPvCYkBkPNAx5w6Mbui",
        "_score": 1.8483887,
        "_source": { "word": "baked" }
      },
      {
        "_index": "glove-vectors",
        "_id": "RoPvCYkBkPNAx5w6NsYl",
        "_score": 1.8451341,
        "_source": { "word": "toast" }
      },
      {
        "_index": "glove-vectors",
        "_id": "o4PvCYkBkPNAx5w6LKCI",
        "_score": 1.84022,
        "_source": { "word": "butter" }
      },
      {
        "_index": "glove-vectors",
        "_id": "koPvCYkBkPNAx5w6LKeK",
        "_score": 1.8374994,
        "_source": { "word": "soup" }
      }
    ]
  }
}

使用 cosine 相似度时,得分范围为 [0, 2]。完全相同的向量得分为 2。

稀疏布尔向量 + LSH #

索引文档 #

PUT /sparse-features/_doc/1
{
  "label": "文档A",
  "features": [[0, 3, 5, 12, 88, 200, 456], 1000]
}

查询示例 #

GET /sparse-features/_search
{
  "size": 5,
  "query": {
    "knn_nearest_neighbors": {
      "field": "features",
      "vec": {
        "values": [[0, 5, 12, 100, 456], 1000]
      },
      "model": "lsh",
      "similarity": "jaccard",
      "candidates": 50
    }
  }
}

精确搜索 #

精确模型计算查询向量与所有索引向量的精确相似度,不使用任何近似索引结构。映射时不需要指定 model,详见 向量字段类型参考

查询 #

GET /exact-index/_search
{
  "query": {
    "knn_nearest_neighbors": {
      "field": "my_vec",
      "vec": {
        "values": [0.1, 0.2, 0.3, ...]
      },
      "model": "exact",
      "similarity": "cosine"
    }
  }
}

⚠️ 精确搜索的时间复杂度为 O(n²),适用于文档数量较少的场景。

精确搜索支持的相似度:

向量类型可用相似度
knn_dense_float_vectorcosinel1l2
knn_sparse_bool_vectorjaccardhamming

引用已索引向量 #

使用索引中已有文档的向量作为查询向量,适用于"查找相似文档"的场景:

GET /my-vectors/_search
{
  "size": 10,
  "query": {
    "knn_nearest_neighbors": {
      "field": "embedding",
      "vec": {
        "index": "my-vectors",
        "id": "doc-1",
        "field": "embedding"
      },
      "model": "lsh",
      "similarity": "cosine",
      "candidates": 100
    }
  }
}

源文档可以在同一索引或不同索引中,只要向量类型和维度匹配即可。


sparse_indexed 模型 #

sparse_indexed 模型使用倒排索引结构,专为稀疏布尔向量设计。映射配置详见 向量字段类型参考

查询 #

GET /sparse-idx/_search
{
  "query": {
    "knn_nearest_neighbors": {
      "field": "features",
      "vec": {
        "values": [[1, 10, 50, 200, 1000], 5000]
      },
      "model": "sparse_indexed",
      "similarity": "jaccard",
      "candidates": 50
    }
  }
}

permutation_lsh 模型 #

permutation_lsh 是基于排列的局部敏感哈希,仅适用于稠密浮点向量。映射配置详见 向量字段类型参考

查询 #

GET /perm-index/_search
{
  "query": {
    "knn_nearest_neighbors": {
      "field": "embedding",
      "vec": {
        "values": [0.1, 0.2, ...]
      },
      "model": "permutation_lsh",
      "similarity": "cosine",
      "candidates": 100
    }
  }
}

与 bool 查询组合 #

向量搜索可以嵌入 bool 查询,与过滤条件组合:

GET /my-vectors/_search
{
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "knn_nearest_neighbors": {
            "field": "embedding",
            "vec": { "values": [0.12, -0.03, ...] },
            "model": "lsh",
            "similarity": "cosine",
            "candidates": 100
          }
        }
      ],
      "filter": [
        { "term": { "category": "tech" } }
      ]
    }
  }
}

与 function_score 集成 #

向量相似度可作为 function_score 的评分函数:

GET /my-vectors/_search
{
  "query": {
    "function_score": {
      "query": { "match": { "title": "搜索引擎" } },
      "functions": [
        {
          "knn_nearest_neighbors": {
            "field": "embedding",
            "vec": { "values": [0.12, -0.03, ...] },
            "model": "lsh",
            "similarity": "cosine",
            "candidates": 100
          },
          "weight": 2
        }
      ],
      "boost_mode": "multiply"
    }
  }
}

相关页面 #