cognee-community-vector-adapter-qdrant 0.0.2__tar.gz → 0.1.0__tar.gz
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-0.1.0/PKG-INFO +54 -0
- cognee_community_vector_adapter_qdrant-0.1.0/README.md +38 -0
- {cognee_community_vector_adapter_qdrant-0.0.2 → cognee_community_vector_adapter_qdrant-0.1.0}/cognee_community_vector_adapter_qdrant/__init__.py +1 -1
- {cognee_community_vector_adapter_qdrant-0.0.2 → cognee_community_vector_adapter_qdrant-0.1.0}/cognee_community_vector_adapter_qdrant/qdrant_adapter.py +100 -56
- {cognee_community_vector_adapter_qdrant-0.0.2 → cognee_community_vector_adapter_qdrant-0.1.0}/pyproject.toml +5 -3
- cognee_community_vector_adapter_qdrant-0.0.2/PKG-INFO +0 -28
- cognee_community_vector_adapter_qdrant-0.0.2/README.md +0 -14
- {cognee_community_vector_adapter_qdrant-0.0.2 → cognee_community_vector_adapter_qdrant-0.1.0}/cognee_community_vector_adapter_qdrant/register.py +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cognee-community-vector-adapter-qdrant
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Qdrant vector database adapter for cognee
|
|
5
|
+
Requires-Python: >=3.11,<=3.13
|
|
6
|
+
Classifier: Programming Language :: Python :: 3
|
|
7
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
8
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
9
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
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)
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
|
|
16
|
+
# Cognee Qdrant Adapter
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
If published, the package can be simply installed via pip:
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
pip install cognee-community-vector-adapter-qdrant
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
In case it is not published yet, you can use poetry to locally build the adapter package:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install poetry
|
|
30
|
+
poetry install # run this command in the directory containing the pyproject.toml file
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Connection Setup
|
|
34
|
+
|
|
35
|
+
For a quick local setup, you can run a docker container that qdrant provides (https://qdrant.tech/documentation/quickstart/).
|
|
36
|
+
After this, you will be able to connect to the Qdrant DB through the appropriate ports. The command for running the docker
|
|
37
|
+
container looks something like the following:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
docker run -p 6333:6333 -p 6334:6334 \
|
|
41
|
+
-v "$(pwd)/qdrant_storage:/qdrant/storage:z" \
|
|
42
|
+
qdrant/qdrant
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
Import and register the adapter in your code:
|
|
48
|
+
```python
|
|
49
|
+
from cognee_community_vector_adapter_qdrant import register
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Example
|
|
53
|
+
See example in `example.py` file.
|
|
54
|
+
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Cognee Qdrant Adapter
|
|
2
|
+
|
|
3
|
+
## Installation
|
|
4
|
+
|
|
5
|
+
If published, the package can be simply installed via pip:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install cognee-community-vector-adapter-qdrant
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
In case it is not published yet, you can use poetry to locally build the adapter package:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pip install poetry
|
|
15
|
+
poetry install # run this command in the directory containing the pyproject.toml file
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Connection Setup
|
|
19
|
+
|
|
20
|
+
For a quick local setup, you can run a docker container that qdrant provides (https://qdrant.tech/documentation/quickstart/).
|
|
21
|
+
After this, you will be able to connect to the Qdrant DB through the appropriate ports. The command for running the docker
|
|
22
|
+
container looks something like the following:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
docker run -p 6333:6333 -p 6334:6334 \
|
|
26
|
+
-v "$(pwd)/qdrant_storage:/qdrant/storage:z" \
|
|
27
|
+
qdrant/qdrant
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Usage
|
|
31
|
+
|
|
32
|
+
Import and register the adapter in your code:
|
|
33
|
+
```python
|
|
34
|
+
from cognee_community_vector_adapter_qdrant import register
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Example
|
|
38
|
+
See example in `example.py` file.
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
from typing import Dict, List, Optional
|
|
3
|
-
from qdrant_client import AsyncQdrantClient, models
|
|
4
|
-
|
|
5
|
-
from cognee.exceptions import InvalidValueError
|
|
6
|
-
from cognee.shared.logging_utils import get_logger
|
|
7
2
|
|
|
8
|
-
from cognee.infrastructure.
|
|
9
|
-
from cognee.infrastructure.engine.utils import parse_id
|
|
3
|
+
from cognee.infrastructure.databases.exceptions import MissingQueryParameterError
|
|
10
4
|
from cognee.infrastructure.databases.vector import VectorDBInterface
|
|
11
|
-
from cognee.infrastructure.databases.vector.
|
|
12
|
-
|
|
5
|
+
from cognee.infrastructure.databases.vector.embeddings.EmbeddingEngine import (
|
|
6
|
+
EmbeddingEngine,
|
|
7
|
+
)
|
|
13
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
|
|
14
14
|
|
|
15
15
|
logger = get_logger("QDrantAdapter")
|
|
16
16
|
|
|
@@ -21,20 +21,19 @@ class IndexSchema(DataPoint):
|
|
|
21
21
|
metadata: dict = {"index_fields": ["text"]}
|
|
22
22
|
|
|
23
23
|
|
|
24
|
-
|
|
25
|
-
def create_hnsw_config(hnsw_config: Dict):
|
|
24
|
+
def create_hnsw_config(hnsw_config: dict):
|
|
26
25
|
if hnsw_config is not None:
|
|
27
26
|
return models.HnswConfig()
|
|
28
27
|
return None
|
|
29
28
|
|
|
30
29
|
|
|
31
|
-
def create_optimizers_config(optimizers_config:
|
|
30
|
+
def create_optimizers_config(optimizers_config: dict):
|
|
32
31
|
if optimizers_config is not None:
|
|
33
32
|
return models.OptimizersConfig()
|
|
34
33
|
return None
|
|
35
34
|
|
|
36
35
|
|
|
37
|
-
def create_quantization_config(quantization_config:
|
|
36
|
+
def create_quantization_config(quantization_config: dict):
|
|
38
37
|
if quantization_config is not None:
|
|
39
38
|
return models.QuantizationConfig()
|
|
40
39
|
return None
|
|
@@ -64,7 +63,7 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
64
63
|
|
|
65
64
|
return AsyncQdrantClient(location=":memory:")
|
|
66
65
|
|
|
67
|
-
async def embed_data(self, data:
|
|
66
|
+
async def embed_data(self, data: list[str]) -> list[float]:
|
|
68
67
|
return await self.embedding_engine.embed_text(data)
|
|
69
68
|
|
|
70
69
|
async def has_collection(self, collection_name: str) -> bool:
|
|
@@ -86,14 +85,15 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
86
85
|
collection_name=collection_name,
|
|
87
86
|
vectors_config={
|
|
88
87
|
"text": models.VectorParams(
|
|
89
|
-
size=self.embedding_engine.get_vector_size(),
|
|
88
|
+
size=self.embedding_engine.get_vector_size(),
|
|
89
|
+
distance="Cosine",
|
|
90
90
|
)
|
|
91
91
|
},
|
|
92
92
|
)
|
|
93
93
|
|
|
94
94
|
await client.close()
|
|
95
95
|
|
|
96
|
-
async def create_data_points(self, collection_name: str, data_points:
|
|
96
|
+
async def create_data_points(self, collection_name: str, data_points: list[DataPoint]):
|
|
97
97
|
from qdrant_client.http.exceptions import UnexpectedResponse
|
|
98
98
|
|
|
99
99
|
client = self.get_qdrant_client()
|
|
@@ -112,7 +112,8 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
112
112
|
points = [convert_to_qdrant_point(point) for point in data_points]
|
|
113
113
|
|
|
114
114
|
try:
|
|
115
|
-
|
|
115
|
+
# Use upsert for AsyncQdrantClient (upload_points doesn't exist or is sync)
|
|
116
|
+
await client.upsert(collection_name=collection_name, points=points)
|
|
116
117
|
except UnexpectedResponse as error:
|
|
117
118
|
if "Collection not found" in str(error):
|
|
118
119
|
raise CollectionNotFoundError(
|
|
@@ -152,15 +153,13 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
152
153
|
async def search(
|
|
153
154
|
self,
|
|
154
155
|
collection_name: str,
|
|
155
|
-
query_text:
|
|
156
|
-
query_vector:
|
|
157
|
-
limit: int = 15,
|
|
156
|
+
query_text: str | None = None,
|
|
157
|
+
query_vector: list[float] | None = None,
|
|
158
|
+
limit: int | None = 15,
|
|
158
159
|
with_vector: bool = False,
|
|
159
|
-
) ->
|
|
160
|
-
from qdrant_client.http.exceptions import UnexpectedResponse
|
|
161
|
-
|
|
160
|
+
) -> list[ScoredResult]:
|
|
162
161
|
if query_text is None and query_vector is None:
|
|
163
|
-
raise
|
|
162
|
+
raise MissingQueryParameterError()
|
|
164
163
|
|
|
165
164
|
if not await self.has_collection(collection_name):
|
|
166
165
|
return []
|
|
@@ -168,44 +167,53 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
168
167
|
if query_vector is None:
|
|
169
168
|
query_vector = (await self.embed_data([query_text]))[0]
|
|
170
169
|
|
|
170
|
+
client = None
|
|
171
171
|
try:
|
|
172
172
|
client = self.get_qdrant_client()
|
|
173
|
-
if limit
|
|
173
|
+
if limit is None:
|
|
174
174
|
collection_size = await client.count(collection_name=collection_name)
|
|
175
|
+
limit = collection_size.count
|
|
176
|
+
if limit == 0:
|
|
177
|
+
await client.close()
|
|
178
|
+
return []
|
|
175
179
|
|
|
176
|
-
|
|
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(
|
|
177
183
|
collection_name=collection_name,
|
|
178
|
-
query_vector
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
if query_vector is not None
|
|
182
|
-
else (await self.embed_data([query_text]))[0],
|
|
183
|
-
),
|
|
184
|
-
limit=limit if limit > 0 else collection_size.count,
|
|
184
|
+
query=query_vector,
|
|
185
|
+
using="text",
|
|
186
|
+
limit=limit,
|
|
185
187
|
with_vectors=with_vector,
|
|
186
188
|
)
|
|
187
189
|
|
|
188
190
|
await client.close()
|
|
189
191
|
|
|
192
|
+
# Extract points from query_result
|
|
193
|
+
results = query_result.points
|
|
194
|
+
|
|
190
195
|
return [
|
|
191
196
|
ScoredResult(
|
|
192
|
-
id=parse_id(result.id),
|
|
197
|
+
id=parse_id(str(result.id)),
|
|
193
198
|
payload={
|
|
194
199
|
**result.payload,
|
|
195
|
-
"id": parse_id(result.id),
|
|
200
|
+
"id": parse_id(str(result.id)),
|
|
196
201
|
},
|
|
197
|
-
score=1 - result.score,
|
|
202
|
+
score=1 - result.score if hasattr(result, 'score') else 1.0,
|
|
198
203
|
)
|
|
199
204
|
for result in results
|
|
200
205
|
]
|
|
201
|
-
|
|
202
|
-
|
|
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 []
|
|
203
211
|
|
|
204
212
|
async def batch_search(
|
|
205
213
|
self,
|
|
206
214
|
collection_name: str,
|
|
207
|
-
query_texts:
|
|
208
|
-
limit: int = None,
|
|
215
|
+
query_texts: list[str],
|
|
216
|
+
limit: int | None = None,
|
|
209
217
|
with_vectors: bool = False,
|
|
210
218
|
):
|
|
211
219
|
"""
|
|
@@ -215,32 +223,50 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
215
223
|
- collection_name (str): Name of the collection to search in.
|
|
216
224
|
- query_texts (List[str]): List of query texts to search for.
|
|
217
225
|
- limit (int): List of result limits for search requests.
|
|
218
|
-
- with_vectors (bool, optional): Bool indicating whether to return
|
|
226
|
+
- with_vectors (bool, optional): Bool indicating whether to return
|
|
227
|
+
vectors for search requests.
|
|
219
228
|
|
|
220
229
|
Returns:
|
|
221
230
|
- results: The search results from Qdrant.
|
|
222
231
|
"""
|
|
223
232
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
with_vector=with_vectors,
|
|
232
|
-
)
|
|
233
|
-
for vector in vectors
|
|
234
|
-
]
|
|
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 []
|
|
235
240
|
|
|
236
241
|
client = self.get_qdrant_client()
|
|
237
242
|
|
|
238
|
-
|
|
239
|
-
|
|
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
|
+
)
|
|
240
252
|
|
|
241
|
-
|
|
253
|
+
await client.close()
|
|
242
254
|
|
|
243
|
-
|
|
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 []
|
|
244
270
|
|
|
245
271
|
async def delete_data_points(self, collection_name: str, data_point_ids: list[str]):
|
|
246
272
|
client = self.get_qdrant_client()
|
|
@@ -256,3 +282,21 @@ class QDrantAdapter(VectorDBInterface):
|
|
|
256
282
|
await client.delete_collection(collection.name)
|
|
257
283
|
|
|
258
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,10 +1,12 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "cognee-community-vector-adapter-qdrant"
|
|
3
|
-
version = "0.0
|
|
3
|
+
version = "0.1.0"
|
|
4
4
|
description = "Qdrant vector database adapter for cognee"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.11,<=3.13"
|
|
7
7
|
dependencies = [
|
|
8
|
-
"qdrant-client>=1.
|
|
9
|
-
"cognee>=0.
|
|
8
|
+
"qdrant-client>=1.16.0",
|
|
9
|
+
"cognee>=0.4.0",
|
|
10
|
+
"starlette>=0.48.0",
|
|
11
|
+
"instructor>=1.11"
|
|
10
12
|
]
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: cognee-community-vector-adapter-qdrant
|
|
3
|
-
Version: 0.0.2
|
|
4
|
-
Summary: Qdrant vector database adapter for cognee
|
|
5
|
-
Requires-Python: >=3.11,<=3.13
|
|
6
|
-
Classifier: Programming Language :: Python :: 3
|
|
7
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
8
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
9
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
10
|
-
Requires-Dist: cognee (>=0.2.1)
|
|
11
|
-
Requires-Dist: qdrant-client (>=1.14.2)
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
|
|
14
|
-
# Cognee Qdrant Adapter
|
|
15
|
-
|
|
16
|
-
## Install
|
|
17
|
-
|
|
18
|
-
Install [`qdrant-client`](https://pypi.org/project/qdrant-client/) in your project.
|
|
19
|
-
|
|
20
|
-
Put this line of code somewhere at the start of the execution, before cognee is initiated.
|
|
21
|
-
|
|
22
|
-
```python
|
|
23
|
-
import packages.vector.qdrant.register
|
|
24
|
-
```
|
|
25
|
-
|
|
26
|
-
## Example
|
|
27
|
-
See example in `example.py` file.
|
|
28
|
-
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# Cognee Qdrant Adapter
|
|
2
|
-
|
|
3
|
-
## Install
|
|
4
|
-
|
|
5
|
-
Install [`qdrant-client`](https://pypi.org/project/qdrant-client/) in your project.
|
|
6
|
-
|
|
7
|
-
Put this line of code somewhere at the start of the execution, before cognee is initiated.
|
|
8
|
-
|
|
9
|
-
```python
|
|
10
|
-
import packages.vector.qdrant.register
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## Example
|
|
14
|
-
See example in `example.py` file.
|