向量数据库Qdrant

404 阅读4分钟

Qdrant(读作:象限)是一个向量相似度搜索引擎和向量数据库。它提供了一个生产就绪的服务,并且有一个方便的 API 来存储、搜索和管理点——带有额外有效载荷的向量。Qdrant 专为扩展过滤支持而设计,使其适用于各种基于神经网络或语义匹配、多维搜索和其他应用程序。

要在本地体验 Qdrant 的全部功能,请使用以下命令运行容器

docker run -p 6333:6333 qdrant/qdrant

启动之后, 可以使用localhost:6333/dashboard访问web UI

image.png

在 Qdrant 中,一个 "collection" 是指一个向量集合,相当于数据库中的表,但是它们专门用于处理向量数据和相关的搜索操作。创建 collection 时,你需要定义一些配置,比如向量的维度、用于计算向量之间距离的度量标准(如欧几里得距离或余弦相似度)等。

image.png

一个point相当于一个数据项,每个点(point)通常包含以下部分:

    {
      "id": 1,
      "vector": [0.1, 0.2, 0.3, ...],
      "payload": {"city": "Berlin"}
    }
  • 唯一标识符(ID):每个点通常有一个唯一的标识符,用于区分集合中的不同点
  • 向量(Vector):这是点的主要部分,是一个数值数组,通常用于表示高维空间中的一个位置,可以用于机器学习模型的输出,如文本嵌入或图像特征
  • 有效载荷(Payload):这是与向量相关联的额外数据。有效载荷可以是任何数据,比如文本字符串、用户ID、标签或其他元数据。有效载荷通常用于在检索到向量后提供更多上下文信息。

创建collection

PUT collections/test_collection
{
  "vectors": {
    "size": 4,
    "distance": "Dot"
  }
}

在 Qdrant 中,distance 参数用于指定计算向量之间相似度时使用的距离度量方法。Qdrant 支持以下几种距离度量:

  • Dot:点积距离度量,用于计算两个向量的点积。点积越高,表示向量越相似。
  • Cosine:余弦相似度,通过将点积除以两个向量的模长之积来计算,用于衡量两个向量在方向上的相似性,范围从 -1 到 1。
  • Euclid:欧几里得距离,用于计算两个向量之间的直线距离,距离越小,表示向量越相似。
  • Manhattan:曼哈顿距离,也称为城市街区距离,用于计算两个向量在各维度上的绝对差值之和。
  • Hamming:汉明距离,用于计算两个向量在相同维度上不同位置的数量(通常用于比较二进制向量)。
  • L2:L2 范数,与欧几里得距离相同,计算两个向量之间的直线距离。
  • L1:L1 范数,与曼哈顿距离相同,计算两个向量在各维度上的绝对差值之和。
  • Linf:L∞ 范数,计算两个向量在所有维度上的最大差异。
  • Tanimoto:主要用于比较稀疏向量,计算的是两个向量中不同位置的数量与至少在一个向量中不同位置的数量之比。
  • Sublinear:子线性时间复杂度的近似最近邻搜索,它使用一种特殊的数据结构来加速搜索过程。

请注意,不同的距离度量方法适用于不同的场景和数据类型。例如,余弦相似度通常用于文本数据,而欧几里得距离适用于连续数值数据。在选择距离度量时,应考虑数据的特性和搜索任务的需求。

添加points

PUT collections/test_collection/points
{
  "points": [
    {
      "id": 1,
      "vector": [0.05, 0.61, 0.76, 0.74],
      "payload": {"city": "Berlin"}
    },
    {
      "id": 2,
      "vector": [0.19, 0.81, 0.75, 0.11],
      "payload": {"city": "London"}
    },
    {
      "id": 3,
      "vector": [0.36, 0.55, 0.47, 0.94],
      "payload": {"city": "Moscow"}
    },
    {
      "id": 4,
      "vector": [0.18, 0.01, 0.85, 0.80],
      "payload": {"city": "New York"}
    },
    {
      "id": 5,
      "vector": [0.24, 0.18, 0.22, 0.44],
      "payload": {"city": "Beijing"}
    },
    {
      "id": 6,
      "vector": [0.35, 0.08, 0.11, 0.44],
      "payload": {"city": "Mumbai"}
    }
  ]
}

查询

POST collections/test_collection/points/search
{
  "vector": [0.2, 0.1, 0.9, 0.7],
  "limit": 3,
  "with_payload": true
}
{
  "result": [
    {
      "id": 4,
      "version": 4,
      "score": 1.362,
      "payload": {
        "city": "New York"
      }
    },
    {
      "id": 1,
      "version": 4,
      "score": 1.273,
      "payload": {
        "city": "Berlin"
      }
    },
    {
      "id": 3,
      "version": 4,
      "score": 1.208,
      "payload": {
        "city": "Moscow"
      }
    }
  ],
  "status": "ok",
  "time": 0.000376471
}

接下来,试验一下,欧几里得距离,用于计算两个向量之间的直线距离,距离越小,表示向量越相似

{
  "vectors": {
    "size": 2,
    "distance": "Euclid"
  }
}
{
  "points": [
    {
      "id": 1,
      "vector": [116.4074, 39.9042],
      "payload": {"city": "北京"}
    },
    {
      "id": 2,
      "vector": [121.4737, 31.2304],
      "payload": {"city": "上海"}
    },
    {
      "id": 3,
      "vector": [117.3616, 39.3434],
      "payload": {"city": "天津"}
    },
    {
      "id": 4,
      "vector": [114.5149, 38.0429],
      "payload": {"city": "石家庄"}
    },
    {
      "id": 5,
      "vector": [114.2986, 30.5931],
      "payload": {"city": "武汉"}
    },
    {
      "id": 6,
      "vector": [117.0014, 36.6510],
      "payload": {"city": "济南"}
    },
    {
      "id": 7,
      "vector": [114.33633, 36.1023],
      "payload": {"city": "安阳"}
    },
    {
      "id": 8,
      "vector": [116.97, 33.63],
      "payload": {"city": "宿州"}
    },
    {
      "id": 9,
      "vector": [118.0119, 36.8062],
      "payload": {"city": "淄博"}
    }
  ]
}

查询

{
  "vector": [117.3616, 39.3434],
  "limit": 3,
  "with_payload": true
}
{
    "result": [
        {
            "id": 3,
            "version": 1,
            "score": 0.0,
            "payload": {
                "city": "天津"
            }
        },
        {
            "id": 1,
            "version": 1,
            "score": 1.1067965,
            "payload": {
                "city": "北京"
            }
        },
        {
            "id": 9,
            "version": 1,
            "score": 2.619213,
            "payload": {
                "city": "淄博"
            }
        }
    ],
    "status": "ok",
    "time": 0.000393092
}

score值越小,越相近。