Skip to content

Commit d5d96a6

Browse files
committed
feat: Qdrant external retriever
1 parent 56bc660 commit d5d96a6

File tree

17 files changed

+872
-3
lines changed

17 files changed

+872
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
- Added unit tests for the Vertex AI LLM class.
1616
- Added support for Cohere LLM and embeddings - added optional dependency to `cohere`.
1717
- Added support for Anthropic LLM - added optional dependency to `anthropic`.
18+
- Added support for Qdrant - added optional dependency to `qdrant-client`.
1819

1920
### Fixed
2021
- Resolved import issue with the Vertex AI Embeddings class.

docs/source/api.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,12 @@ PineconeNeo4jRetriever
136136
.. autoclass:: neo4j_graphrag.retrievers.external.pinecone.pinecone.PineconeNeo4jRetriever
137137
:members: search
138138

139+
QdrantNeo4jRetriever
140+
======================
141+
142+
.. autoclass:: neo4j_graphrag.retrievers.external.qdrant.qdrant.QdrantNeo4jRetriever
143+
:members: search
144+
139145

140146
********
141147
Embedder

docs/source/user_guide_rag.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -327,6 +327,8 @@ We provide implementations for the following retrievers:
327327
- Use this retriever when vectors are saved in a Weaviate vector database
328328
* - :ref:`PineconeNeo4jRetriever <pinecone-neo4j-retriever-user-guide>`
329329
- Use this retriever when vectors are saved in a Pinecone vector database
330+
* - :ref:`QdrantNeo4jRetriever <qdrant-neo4j-retriever-user-guide>`
331+
- Use this retriever when vectors are saved in a Qdrant vector database
330332

331333
Retrievers all expose a `search` method that we will discuss in the next sections.
332334

@@ -670,6 +672,35 @@ Pinecone Retrievers
670672
671673
Also see :ref:`pineconeneo4jretriever`.
672674

675+
.. _qdrant-neo4j-retriever-user-guide:
676+
677+
Qdrant Retrievers
678+
-------------------
679+
680+
.. note::
681+
682+
In order to import this retriever, the Qdrant Python client must be installed:
683+
`pip install qdrant-client`
684+
685+
686+
.. code:: python
687+
688+
from qdrant_client import QdrantClient
689+
from neo4j_graphrag.retrievers import QdrantNeo4jRetriever
690+
691+
client = QdrantClient(...) # construct the Qdrant client instance
692+
693+
retriever = QdrantNeo4jRetriever(
694+
driver=driver,
695+
client=client,
696+
collection_name="my-collection",
697+
id_property_external="neo4j_id", # The payload field that contains identifier to a corresponding Neo4j node id property
698+
id_property_neo4j="id",
699+
embedder=embedder,
700+
)
701+
702+
See :ref:`qdrantneo4jretriever`.
703+
673704

674705
Other Retrievers
675706
===================

examples/qdrant/README.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
### Start services locally
2+
3+
Run the following command to spin up Neo4j and Qdrant containers.
4+
5+
```bash
6+
docker compose -f tests/e2e/docker-compose.yml up
7+
```
8+
9+
### Write data (once)
10+
11+
Run this from the project root to write data to both Neo4J and Qdrant.
12+
13+
```bash
14+
poetry run python tests/e2e/qdrant_e2e/populate_dbs.py
15+
```
16+
17+
### Install Qdrant client
18+
19+
```bash
20+
pip install qdrant-client
21+
```
22+
23+
### Search
24+
25+
```bash
26+
# search by vector
27+
poetry run python -m examples.qdrant.vector_search
28+
29+
# search by text, with embeddings generated locally
30+
poetry run python -m examples.qdrant.text_search
31+
```

examples/qdrant/__init__.py

Whitespace-only changes.

examples/qdrant/text_search.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from langchain_huggingface.embeddings import HuggingFaceEmbeddings
2+
from neo4j import GraphDatabase
3+
from neo4j_graphrag.retrievers import QdrantNeo4jRetriever
4+
from qdrant_client import QdrantClient
5+
6+
NEO4J_URL = "neo4j://localhost:7687"
7+
NEO4J_AUTH = ("neo4j", "password")
8+
9+
10+
def main() -> None:
11+
with GraphDatabase.driver(NEO4J_URL, auth=NEO4J_AUTH) as neo4j_driver:
12+
embedder = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")
13+
retriever = QdrantNeo4jRetriever(
14+
driver=neo4j_driver,
15+
client=QdrantClient(url="http://localhost:6333"),
16+
collection_name="Jeopardy",
17+
id_property_external="neo4j_id",
18+
id_property_neo4j="id",
19+
embedder=embedder, # type: ignore
20+
)
21+
22+
res = retriever.search(query_text="biology", top_k=2)
23+
print(res)
24+
25+
26+
if __name__ == "__main__":
27+
main()

examples/qdrant/vector_search.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from neo4j import GraphDatabase
2+
from neo4j_graphrag.retrievers import QdrantNeo4jRetriever
3+
from qdrant_client import QdrantClient
4+
5+
from examples.embedding_biology import EMBEDDING_BIOLOGY
6+
7+
NEO4J_URL = "neo4j://localhost:7687"
8+
NEO4J_AUTH = ("neo4j", "password")
9+
10+
11+
def main() -> None:
12+
with GraphDatabase.driver(NEO4J_URL, auth=NEO4J_AUTH) as neo4j_driver:
13+
retriever = QdrantNeo4jRetriever(
14+
driver=neo4j_driver,
15+
client=QdrantClient(url="http://localhost:6333"),
16+
collection_name="Jeopardy",
17+
id_property_external="neo4j_id",
18+
id_property_neo4j="id",
19+
)
20+
res = retriever.search(query_vector=EMBEDDING_BIOLOGY, top_k=2)
21+
print(res)
22+
23+
24+
if __name__ == "__main__":
25+
main()

src/neo4j_graphrag/retrievers/__init__.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,10 @@
4040
__all__.append("WeaviateNeo4jRetriever")
4141
except ImportError:
4242
pass
43+
44+
try:
45+
from .external.qdrant.qdrant import QdrantNeo4jRetriever # noqa: F401
46+
47+
__all__.append("QdrantNeo4jRetriever")
48+
except ImportError:
49+
pass
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# Copyright (c) "Neo4j"
2+
# Neo4j Sweden AB [https://neo4j.com]
3+
# #
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
# #
8+
# https://www.apache.org/licenses/LICENSE-2.0
9+
# #
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.

0 commit comments

Comments
 (0)