fix: 适配qdrant-client 1.17.0 API变更,search方法改为query_points
- qdrant-client 1.10+ 版本移除了 search() 方法,改用 query_points() - 使用 collection_exists() 替代 get_collections() 检查集合存在 - 更新返回结果处理:results.points 替代 results - 更新 pyproject.toml 版本约束为 >=1.9.0,<2.0.0 - 修正 README.md 中的 docker 命令示例
This commit is contained in:
parent
d660c19ab9
commit
2c35047dc2
|
|
@ -114,10 +114,10 @@ docker exec -it ai-ollama ollama pull toshk0/nomic-embed-text-v2-moe:Q6_K
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 检查服务状态
|
# 检查服务状态
|
||||||
docker compose ps
|
docker ps
|
||||||
|
|
||||||
# 查看后端日志,找到自动生成的 API Key
|
# 查看后端日志,找到自动生成的 API Key
|
||||||
docker compose logs -f ai-service | grep "Default API Key"
|
docker logs -f ai-service | grep "Default API Key"
|
||||||
```
|
```
|
||||||
|
|
||||||
> **重要**: 后端首次启动时会自动生成一个默认 API Key,请从日志中复制该 Key,用于前端配置。
|
> **重要**: 后端首次启动时会自动生成一个默认 API Key,请从日志中复制该 Key,用于前端配置。
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ import logging
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
from qdrant_client import AsyncQdrantClient
|
from qdrant_client import AsyncQdrantClient
|
||||||
from qdrant_client.models import Distance, PointStruct, VectorParams, MultiVectorConfig
|
from qdrant_client.models import Distance, PointStruct, VectorParams, QueryRequest
|
||||||
|
|
||||||
from app.core.config import get_settings
|
from app.core.config import get_settings
|
||||||
|
|
||||||
|
|
@ -61,8 +61,7 @@ class QdrantClient:
|
||||||
collection_name = self.get_collection_name(tenant_id)
|
collection_name = self.get_collection_name(tenant_id)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
collections = await client.get_collections()
|
exists = await client.collection_exists(collection_name)
|
||||||
exists = any(c.name == collection_name for c in collections.collections)
|
|
||||||
|
|
||||||
if not exists:
|
if not exists:
|
||||||
if use_multi_vector:
|
if use_multi_vector:
|
||||||
|
|
@ -213,36 +212,42 @@ class QdrantClient:
|
||||||
try:
|
try:
|
||||||
logger.info(f"[AC-AISVC-10] Searching in collection: {collection_name}")
|
logger.info(f"[AC-AISVC-10] Searching in collection: {collection_name}")
|
||||||
|
|
||||||
|
exists = await client.collection_exists(collection_name)
|
||||||
|
if not exists:
|
||||||
|
logger.warning(f"[AC-AISVC-10] Collection {collection_name} does not exist")
|
||||||
|
continue
|
||||||
|
|
||||||
try:
|
try:
|
||||||
results = await client.search(
|
results = await client.query_points(
|
||||||
collection_name=collection_name,
|
collection_name=collection_name,
|
||||||
query_vector=(vector_name, query_vector),
|
query=query_vector,
|
||||||
|
using=vector_name,
|
||||||
limit=limit,
|
limit=limit,
|
||||||
with_vectors=with_vectors,
|
with_vectors=with_vectors,
|
||||||
|
score_threshold=score_threshold,
|
||||||
)
|
)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if "vector name" in str(e).lower() or "Not existing vector" in str(e):
|
if "vector name" in str(e).lower() or "Not existing vector" in str(e) or "using" in str(e).lower():
|
||||||
logger.info(
|
logger.info(
|
||||||
f"[AC-AISVC-10] Collection {collection_name} doesn't have vector named '{vector_name}', "
|
f"[AC-AISVC-10] Collection {collection_name} doesn't have vector named '{vector_name}', "
|
||||||
f"trying without vector name (single-vector mode)"
|
f"trying without vector name (single-vector mode)"
|
||||||
)
|
)
|
||||||
results = await client.search(
|
results = await client.query_points(
|
||||||
collection_name=collection_name,
|
collection_name=collection_name,
|
||||||
query_vector=query_vector,
|
query=query_vector,
|
||||||
limit=limit,
|
limit=limit,
|
||||||
with_vectors=with_vectors,
|
with_vectors=with_vectors,
|
||||||
|
score_threshold=score_threshold,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
|
|
||||||
logger.info(
|
logger.info(
|
||||||
f"[AC-AISVC-10] Collection {collection_name} returned {len(results)} raw results"
|
f"[AC-AISVC-10] Collection {collection_name} returned {len(results.points)} raw results"
|
||||||
)
|
)
|
||||||
|
|
||||||
hits = []
|
hits = []
|
||||||
for result in results:
|
for result in results.points:
|
||||||
if score_threshold is not None and result.score < score_threshold:
|
|
||||||
continue
|
|
||||||
hit = {
|
hit = {
|
||||||
"id": str(result.id),
|
"id": str(result.id),
|
||||||
"score": result.score,
|
"score": result.score,
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ dependencies = [
|
||||||
"tenacity>=8.2.0",
|
"tenacity>=8.2.0",
|
||||||
"sqlmodel>=0.0.14",
|
"sqlmodel>=0.0.14",
|
||||||
"asyncpg>=0.29.0",
|
"asyncpg>=0.29.0",
|
||||||
"qdrant-client>=1.7.0",
|
"qdrant-client>=1.9.0,<2.0.0",
|
||||||
"tiktoken>=0.5.0",
|
"tiktoken>=0.5.0",
|
||||||
"openpyxl>=3.1.0",
|
"openpyxl>=3.1.0",
|
||||||
"python-docx>=1.1.0",
|
"python-docx>=1.1.0",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue