向量查询
> 文档中心 > 文档中心 > INFINI Easysearch > 功能手册 > 搜索操作 > 向量查询

向量查询 #

使用 kNN 检索 API 来进行向量查询。


先决条件 #

要运行 kNN 搜索,必须安装 knn 插件,参考 插件安装

创建 Mapping 和 Setting #

在索引向量之前,首先定义一个 Mapping,指定向量数据类型、索引模型和模型的参数。这决定了索引向量支持哪些查询。
并指定 index.knn 为 true ,这是为了启用近似相似度模型。

请求示例 #

PUT /knn-test
{
  "settings": {
    "index.knn": true
  },
  "mappings": {
    "properties": {
      "my_vec": {
        "type": "knn_dense_float_vector",
        "knn": {
          "dims": 50,
          "model": "lsh",
          "similarity": "cosine",
          "L": 99,
          "k": 1
        }
      }
    }
  }
}

参数说明 #

  • my_vec 存储向量的字段名称
  • knn_dense_float_vector 表示数据类型为密集型浮点向量.

knn 字典对象,对象中的各个参数含义如下:

  • dims:向量的维度。
  • model:模型类型。
  • similarity:相似度类型。
  • L:哈希表的数量。一般来说,增加此值会增加召回率。
  • k:用于形成单个哈希值的哈希函数的数量。一般来说,增加此值会增加精度。

导入测试向量数据 #

我这里采用斯坦福大学预训练好的词向量来演示 https://huggingface.co/stanfordnlp/glove/resolve/main/glove.6B.zip

下载后解压,导入 glove.6B.50d.txt 到 Easysearch,这个文件里每个词是 50 维度的向量。

将单词存为 word 字段,向量存为 my_vec 字段。

检索向量 #

以 bread 单词为例,先从索引中查出 bread 单词的向量。

请求示例 #

GET knn-test/_search
{
  "query": {
    "match": {
      "word": "bread"
    }
  }
}

然后用 bread 的向量到索引中查询和它相近的词。

请求示例 #

GET knn-test/_search
{
  "size": 10,
  "_source": "word",
  "query": {
    "bool": {
      "must": [
        {
          "knn_nearest_neighbors": {
            "field": "my_vec",
            "vec": {
              "values": [
                -0.37436,
                -0.11959,
                -0.87609,
                -1.1217,
                1.2788,
                0.48323,
                -0.53903,
                0.053659,
                -0.23929,
                -0.12414,
                ......
              ]
            },
            "model": "lsh",
            "similarity": "cosine",
            "candidates": 50
          }
        }
      ]
    }
  }
}

示例响应 #

返回的词都是和 bread 含义相近或者经常一起出现的。

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

精确映射(Exact Mapping) #

精确模型允许您运行精确搜索。这些搜索不使用任何索引结构,其运行时间为 O(n^2),其中 n 是文档总数。
使用该模型不需要提供任何模型参数。

请求示例 #

PUT /my-index/_mapping
{
    "properties": {
        "my_vec": {
            "type": "knn_(dense_float | sparse_bool)_vector",  # 1. 向量数据类型
            "knn": {
                "dims": 100   # 2. 向量的维度
            }
        }
    }
}

注意,使用精确模型可以进行精确搜索,但计算开销较大,适用于文档数量较少的情况。

精确查询(Exact Query) #

计算查询向量与所有索引向量之间的精确相似度。相对于近似搜索,该算法效率较低,但实现已经经过广泛的优化和分析。

请求示例 #

GET /my-index/_search
{
    "query": {
        "knn_nearest_neighbors": {
            "field": "my_vec",
            "vec": {                                # 1
                "values": [0.1, 0.2, 0.3, ...],
            },
            "model": "exact",                       # 2
            "similarity": "(cosine | l1 | l2)",    # 3
        }
    }
}

参数说明 #

#1 查询向量。必须匹配 my_vec 的数据类型
#2 模型名称。
#3 相似性函数。必须与向量类型兼容