# Copyright (c) "Neo4j" # Neo4j Sweden AB [https://neo4j.com] # # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # # https://www.apache.org/licenses/LICENSE-2.0 # # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. import re from typing import Any, Generator from unittest import mock from unittest.mock import MagicMock import pytest from neo4j_graphrag.embeddings.base import Embedder from neo4j_graphrag.embeddings.sentence_transformers import ( SentenceTransformerEmbeddings, ) from neo4j_graphrag.retrievers import PineconeNeo4jRetriever from neo4j_graphrag.types import RetrieverResult, RetrieverResultItem from pinecone import Pinecone from ..utils import EMBEDDING_BIOLOGY, build_data_objects, populate_neo4j @pytest.fixture(scope="module") def sentence_transformer_embedder() -> ( Generator[SentenceTransformerEmbeddings, Any, Any] ): embedder = SentenceTransformerEmbeddings(model="all-MiniLM-L6-v2") yield embedder @pytest.fixture(scope="module") def client() -> MagicMock: return MagicMock(spec=Pinecone) @pytest.fixture(scope="module") def populate_neo4j_db(driver: MagicMock) -> None: driver.execute_query("MATCH (n) DETACH DELETE n") neo4j_objects, _ = build_data_objects("pinecone") populate_neo4j(driver, neo4j_objects) @pytest.mark.usefixtures("populate_neo4j_db") def test_pinecone_neo4j_vector_input(driver: MagicMock, client: MagicMock) -> None: retriever = PineconeNeo4jRetriever( driver=driver, client=client, index_name="jeopardy", id_property_neo4j="id", node_label_neo4j="`Question`", ) with mock.patch.object(retriever, "index") as mock_index: top_k = 2 mock_index.query.return_value = { "matches": [ { "id": "question_c458c6f64d8d47429636bc5a94c97f51", "score": 0.232427984, "values": [], }, { "id": "question_3d53154d16068c1e86e024923bc220d8", "score": 0.184265107, "values": [], }, ], "namespace": "", "usage": {"read_units": 5}, } results = retriever.search(query_vector=EMBEDDING_BIOLOGY, top_k=top_k) assert isinstance(results, RetrieverResult) assert len(results.items) == top_k for result in results.items: assert isinstance(result, RetrieverResultItem) pattern = ( r" " r"score=0.232427984>" ) assert re.match(pattern, results.items[0].content) @pytest.mark.usefixtures("populate_neo4j_db") def test_pinecone_neo4j_text_input( driver: MagicMock, client: MagicMock, sentence_transformer_embedder: Embedder ) -> None: retriever = PineconeNeo4jRetriever( driver=driver, client=client, index_name="jeopardy", id_property_neo4j="id", embedder=sentence_transformer_embedder, ) with mock.patch.object(retriever, "index") as mock_index: top_k = 2 mock_index.query.return_value = { "matches": [ { "id": "question_c458c6f64d8d47429636bc5a94c97f51", "score": 0.232427984, "values": [], }, { "id": "question_3d53154d16068c1e86e024923bc220d8", "score": 0.184265107, "values": [], }, ], "namespace": "", "usage": {"read_units": 5}, } results = retriever.search(query_text="biology", top_k=top_k) assert isinstance(results, RetrieverResult) assert len(results.items) == top_k for result in results.items: assert isinstance(result, RetrieverResultItem) pattern = ( r" " r"score=0.232427984>" ) assert re.match(pattern, results.items[0].content)