cognee-community-vector-adapter-qdrant 0.0.3__py3-none-any.whl → 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cognee_community_vector_adapter_qdrant/qdrant_adapter.py +91 -63
- {cognee_community_vector_adapter_qdrant-0.0.3.dist-info → cognee_community_vector_adapter_qdrant-0.1.0.dist-info}/METADATA +6 -4
- cognee_community_vector_adapter_qdrant-0.1.0.dist-info/RECORD +6 -0
- {cognee_community_vector_adapter_qdrant-0.0.3.dist-info → cognee_community_vector_adapter_qdrant-0.1.0.dist-info}/WHEEL +1 -1
- cognee_community_vector_adapter_qdrant-0.0.3.dist-info/RECORD +0 -6
|
@@ -1,18 +1,16 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
from typing import Dict, List, Optional
|
|
3
|
-
from qdrant_client import AsyncQdrantClient, models
|
|
4
|
-
|
|
5
|
-
from cognee.shared.logging_utils import get_logger
|
|
6
2
|
|
|
7
|
-
from cognee.infrastructure.engine import DataPoint
|
|
8
|
-
from cognee.infrastructure.engine.utils import parse_id
|
|
9
3
|
from cognee.infrastructure.databases.exceptions import MissingQueryParameterError
|
|
10
4
|
from cognee.infrastructure.databases.vector import VectorDBInterface
|
|
11
|
-
from cognee.infrastructure.databases.vector.models.ScoredResult import ScoredResult
|
|
12
5
|
from cognee.infrastructure.databases.vector.embeddings.EmbeddingEngine import (
|
|
13
6
|
EmbeddingEngine,
|
|
14
7
|
)
|
|
15
8
|
from cognee.infrastructure.databases.vector.exceptions import CollectionNotFoundError
|
|
9
|
+
from cognee.infrastructure.databases.vector.models.ScoredResult import ScoredResult
|
|
10
|
+
from cognee.infrastructure.engine import DataPoint
|
|
11
|
+
from cognee.infrastructure.engine.utils import parse_id
|
|
12
|
+
from cognee.shared.logging_utils import get_logger
|
|
13
|
+
from qdrant_client import AsyncQdrantClient, models
|
|
16
14
|
|
|
17
15
|
logger = get_logger("QDrantAdapter")
|
|
18
16
|
|
|
@@ -23,19 +21,19 @@ class IndexSchema(DataPoint):
|
|
|
23
21
|
metadata: dict = {"index_fields": ["text"]}
|
|
24
22
|
|
|
25
23
|
|
|
26
|
-
def create_hnsw_config(hnsw_config:
|
|
24
|
+
def create_hnsw_config(hnsw_config: dict):
|
|
27
25
|
if hnsw_config is not None:
|
|
28
26
|
return models.HnswConfig()
|
|
29
27
|
return None
|
|
30
28
|
|
|
31
29
|
|
|
32
|
-
def create_optimizers_config(optimizers_config:
|
|
30
|
+
def create_optimizers_config(optimizers_config: dict):
|
|
33
31
|
if optimizers_config is not None:
|
|
34
32
|
return models.OptimizersConfig()
|
|
35
33
|
return None
|
|
36
34
|
|
|
37
35
|
|
|
38
|
-
def create_quantization_config(quantization_config:
|
|
36
|
+
def create_quantization_config(quantization_config: dict):
|
|
39
37
|
if quantization_config is not None:
|
|
40
38
|
return models.QuantizationConfig()
|
|
41
39
|
return None
|
|
@@ -47,9 +45,7 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
47
45
|
api_key: str = None
|
|
48
46
|
qdrant_path: str = None
|
|
49
47
|
|
|
50
|
-
def __init__(
|
|
51
|
-
self, url, api_key, embedding_engine: EmbeddingEngine, qdrant_path=None
|
|
52
|
-
):
|
|
48
|
+
def __init__(self, url, api_key, embedding_engine: EmbeddingEngine, qdrant_path=None):
|
|
53
49
|
self.embedding_engine = embedding_engine
|
|
54
50
|
|
|
55
51
|
if qdrant_path is not None:
|
|
@@ -67,7 +63,7 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
67
63
|
|
|
68
64
|
return AsyncQdrantClient(location=":memory:")
|
|
69
65
|
|
|
70
|
-
async def embed_data(self, data:
|
|
66
|
+
async def embed_data(self, data: list[str]) -> list[float]:
|
|
71
67
|
return await self.embedding_engine.embed_text(data)
|
|
72
68
|
|
|
73
69
|
async def has_collection(self, collection_name: str) -> bool:
|
|
@@ -97,9 +93,7 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
97
93
|
|
|
98
94
|
await client.close()
|
|
99
95
|
|
|
100
|
-
async def create_data_points(
|
|
101
|
-
self, collection_name: str, data_points: List[DataPoint]
|
|
102
|
-
):
|
|
96
|
+
async def create_data_points(self, collection_name: str, data_points: list[DataPoint]):
|
|
103
97
|
from qdrant_client.http.exceptions import UnexpectedResponse
|
|
104
98
|
|
|
105
99
|
client = self.get_qdrant_client()
|
|
@@ -118,7 +112,8 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
118
112
|
points = [convert_to_qdrant_point(point) for point in data_points]
|
|
119
113
|
|
|
120
114
|
try:
|
|
121
|
-
|
|
115
|
+
# Use upsert for AsyncQdrantClient (upload_points doesn't exist or is sync)
|
|
116
|
+
await client.upsert(collection_name=collection_name, points=points)
|
|
122
117
|
except UnexpectedResponse as error:
|
|
123
118
|
if "Collection not found" in str(error):
|
|
124
119
|
raise CollectionNotFoundError(
|
|
@@ -151,22 +146,18 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
151
146
|
|
|
152
147
|
async def retrieve(self, collection_name: str, data_point_ids: list[str]):
|
|
153
148
|
client = self.get_qdrant_client()
|
|
154
|
-
results = await client.retrieve(
|
|
155
|
-
collection_name, data_point_ids, with_payload=True
|
|
156
|
-
)
|
|
149
|
+
results = await client.retrieve(collection_name, data_point_ids, with_payload=True)
|
|
157
150
|
await client.close()
|
|
158
151
|
return results
|
|
159
152
|
|
|
160
153
|
async def search(
|
|
161
154
|
self,
|
|
162
155
|
collection_name: str,
|
|
163
|
-
query_text:
|
|
164
|
-
query_vector:
|
|
165
|
-
limit: int = 15,
|
|
156
|
+
query_text: str | None = None,
|
|
157
|
+
query_vector: list[float] | None = None,
|
|
158
|
+
limit: int | None = 15,
|
|
166
159
|
with_vector: bool = False,
|
|
167
|
-
) ->
|
|
168
|
-
from qdrant_client.http.exceptions import UnexpectedResponse
|
|
169
|
-
|
|
160
|
+
) -> list[ScoredResult]:
|
|
170
161
|
if query_text is None and query_vector is None:
|
|
171
162
|
raise MissingQueryParameterError()
|
|
172
163
|
|
|
@@ -176,47 +167,53 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
176
167
|
if query_vector is None:
|
|
177
168
|
query_vector = (await self.embed_data([query_text]))[0]
|
|
178
169
|
|
|
170
|
+
client = None
|
|
179
171
|
try:
|
|
180
172
|
client = self.get_qdrant_client()
|
|
181
|
-
if limit
|
|
173
|
+
if limit is None:
|
|
182
174
|
collection_size = await client.count(collection_name=collection_name)
|
|
183
175
|
limit = collection_size.count
|
|
184
176
|
if limit == 0:
|
|
177
|
+
await client.close()
|
|
185
178
|
return []
|
|
186
179
|
|
|
187
|
-
|
|
180
|
+
# Use query_points instead of search (API change in qdrant-client)
|
|
181
|
+
# query_points is the correct method for AsyncQdrantClient
|
|
182
|
+
query_result = await client.query_points(
|
|
188
183
|
collection_name=collection_name,
|
|
189
|
-
query_vector
|
|
190
|
-
|
|
191
|
-
vector=query_vector
|
|
192
|
-
if query_vector is not None
|
|
193
|
-
else (await self.embed_data([query_text]))[0],
|
|
194
|
-
),
|
|
184
|
+
query=query_vector,
|
|
185
|
+
using="text",
|
|
195
186
|
limit=limit,
|
|
196
187
|
with_vectors=with_vector,
|
|
197
188
|
)
|
|
198
189
|
|
|
199
190
|
await client.close()
|
|
200
191
|
|
|
192
|
+
# Extract points from query_result
|
|
193
|
+
results = query_result.points
|
|
194
|
+
|
|
201
195
|
return [
|
|
202
196
|
ScoredResult(
|
|
203
|
-
id=parse_id(result.id),
|
|
197
|
+
id=parse_id(str(result.id)),
|
|
204
198
|
payload={
|
|
205
199
|
**result.payload,
|
|
206
|
-
"id": parse_id(result.id),
|
|
200
|
+
"id": parse_id(str(result.id)),
|
|
207
201
|
},
|
|
208
|
-
score=1 - result.score,
|
|
202
|
+
score=1 - result.score if hasattr(result, 'score') else 1.0,
|
|
209
203
|
)
|
|
210
204
|
for result in results
|
|
211
205
|
]
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
except Exception as e:
|
|
207
|
+
logger.error(f"Error in Qdrant search: {e}", exc_info=True)
|
|
208
|
+
if client:
|
|
209
|
+
await client.close()
|
|
210
|
+
return []
|
|
214
211
|
|
|
215
212
|
async def batch_search(
|
|
216
213
|
self,
|
|
217
214
|
collection_name: str,
|
|
218
|
-
query_texts:
|
|
219
|
-
limit: int = None,
|
|
215
|
+
query_texts: list[str],
|
|
216
|
+
limit: int | None = None,
|
|
220
217
|
with_vectors: bool = False,
|
|
221
218
|
):
|
|
222
219
|
"""
|
|
@@ -226,37 +223,50 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
226
223
|
- collection_name (str): Name of the collection to search in.
|
|
227
224
|
- query_texts (List[str]): List of query texts to search for.
|
|
228
225
|
- limit (int): List of result limits for search requests.
|
|
229
|
-
- with_vectors (bool, optional): Bool indicating whether to return
|
|
226
|
+
- with_vectors (bool, optional): Bool indicating whether to return
|
|
227
|
+
vectors for search requests.
|
|
230
228
|
|
|
231
229
|
Returns:
|
|
232
230
|
- results: The search results from Qdrant.
|
|
233
231
|
"""
|
|
234
232
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
with_vector=with_vectors,
|
|
243
|
-
)
|
|
244
|
-
for vector in vectors
|
|
245
|
-
]
|
|
233
|
+
client = self.get_qdrant_client()
|
|
234
|
+
if limit is None:
|
|
235
|
+
collection_size = await client.count(collection_name=collection_name)
|
|
236
|
+
limit = collection_size.count
|
|
237
|
+
if limit == 0:
|
|
238
|
+
await client.close()
|
|
239
|
+
return []
|
|
246
240
|
|
|
247
241
|
client = self.get_qdrant_client()
|
|
248
242
|
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
243
|
+
try:
|
|
244
|
+
# Use query_batch instead of search_batch (API change in qdrant-client)
|
|
245
|
+
# query_batch is the correct method for AsyncQdrantClient
|
|
246
|
+
query_results = await client.query_batch(
|
|
247
|
+
collection_name=collection_name,
|
|
248
|
+
query_texts=query_texts,
|
|
249
|
+
limit=limit,
|
|
250
|
+
with_vectors=with_vectors,
|
|
251
|
+
)
|
|
253
252
|
|
|
254
|
-
|
|
253
|
+
await client.close()
|
|
255
254
|
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
for
|
|
259
|
-
|
|
255
|
+
# Extract points from each query result and filter by score
|
|
256
|
+
filtered_results = []
|
|
257
|
+
for query_result in query_results:
|
|
258
|
+
points = query_result.points if hasattr(query_result, 'points') else []
|
|
259
|
+
filtered_points = [
|
|
260
|
+
result for result in points
|
|
261
|
+
if hasattr(result, 'score') and result.score > 0.9
|
|
262
|
+
]
|
|
263
|
+
filtered_results.append(filtered_points)
|
|
264
|
+
|
|
265
|
+
return filtered_results
|
|
266
|
+
except Exception as e:
|
|
267
|
+
logger.error(f"Error in Qdrant batch_search: {e}", exc_info=True)
|
|
268
|
+
await client.close()
|
|
269
|
+
return []
|
|
260
270
|
|
|
261
271
|
async def delete_data_points(self, collection_name: str, data_point_ids: list[str]):
|
|
262
272
|
client = self.get_qdrant_client()
|
|
@@ -272,3 +282,21 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
272
282
|
await client.delete_collection(collection.name)
|
|
273
283
|
|
|
274
284
|
await client.close()
|
|
285
|
+
|
|
286
|
+
async def get_collection_names(self) -> list[str]:
|
|
287
|
+
"""
|
|
288
|
+
Get names of all collections in the database.
|
|
289
|
+
|
|
290
|
+
Returns:
|
|
291
|
+
list[str]: List of collection names.
|
|
292
|
+
"""
|
|
293
|
+
|
|
294
|
+
client = self.get_qdrant_client()
|
|
295
|
+
|
|
296
|
+
response = await client.get_collections()
|
|
297
|
+
|
|
298
|
+
result = [collection.name for collection in response.collections]
|
|
299
|
+
|
|
300
|
+
await client.close()
|
|
301
|
+
|
|
302
|
+
return result
|
|
@@ -1,14 +1,16 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: cognee-community-vector-adapter-qdrant
|
|
3
|
-
Version: 0.0
|
|
3
|
+
Version: 0.1.0
|
|
4
4
|
Summary: Qdrant vector database adapter for cognee
|
|
5
5
|
Requires-Python: >=3.11,<=3.13
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
7
7
|
Classifier: Programming Language :: Python :: 3.11
|
|
8
8
|
Classifier: Programming Language :: Python :: 3.12
|
|
9
9
|
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
-
Requires-Dist: cognee (>=0.
|
|
11
|
-
Requires-Dist:
|
|
10
|
+
Requires-Dist: cognee (>=0.4.0)
|
|
11
|
+
Requires-Dist: instructor (>=1.11)
|
|
12
|
+
Requires-Dist: qdrant-client (>=1.16.0)
|
|
13
|
+
Requires-Dist: starlette (>=0.48.0)
|
|
12
14
|
Description-Content-Type: text/markdown
|
|
13
15
|
|
|
14
16
|
# Cognee Qdrant Adapter
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
cognee_community_vector_adapter_qdrant/__init__.py,sha256=OYsRMTyBnNuusKB3rkQmwCppfdEf__AuXMw_Ma1k6lQ,71
|
|
2
|
+
cognee_community_vector_adapter_qdrant/qdrant_adapter.py,sha256=hFMmSaUArnhTZHR8I9VW3fHdmO-1VHw8TD9-fJ4rs-c,10379
|
|
3
|
+
cognee_community_vector_adapter_qdrant/register.py,sha256=K0cIQGN3an79wWCMXAIgwsymkloHGV2_joy7G-4aiB8,158
|
|
4
|
+
cognee_community_vector_adapter_qdrant-0.1.0.dist-info/METADATA,sha256=0dcxsPnOFHs-gDGnrmFJR9up07mdE6AAQ7tkvRhnPbA,1537
|
|
5
|
+
cognee_community_vector_adapter_qdrant-0.1.0.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
|
|
6
|
+
cognee_community_vector_adapter_qdrant-0.1.0.dist-info/RECORD,,
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
cognee_community_vector_adapter_qdrant/__init__.py,sha256=OYsRMTyBnNuusKB3rkQmwCppfdEf__AuXMw_Ma1k6lQ,71
|
|
2
|
-
cognee_community_vector_adapter_qdrant/qdrant_adapter.py,sha256=7asKZ88lMtkEK12p0oZpOR5BdxVPFE7S74fghp5B6ec,9042
|
|
3
|
-
cognee_community_vector_adapter_qdrant/register.py,sha256=K0cIQGN3an79wWCMXAIgwsymkloHGV2_joy7G-4aiB8,158
|
|
4
|
-
cognee_community_vector_adapter_qdrant-0.0.3.dist-info/METADATA,sha256=j3c11rgh4DzvPAvyYo8h5SnvCplSAy8SwWf9S770iQ0,1466
|
|
5
|
-
cognee_community_vector_adapter_qdrant-0.0.3.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
|
6
|
-
cognee_community_vector_adapter_qdrant-0.0.3.dist-info/RECORD,,
|