# 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 pytest from neo4j import Driver from neo4j_graphrag.embeddings.base import Embedder from neo4j_graphrag.retrievers import VectorCypherRetriever, VectorRetriever from neo4j_graphrag.types import RetrieverResult, RetrieverResultItem @pytest.mark.usefixtures("setup_neo4j_for_retrieval") def test_vector_retriever_search_text( driver: Driver, random_embedder: Embedder ) -> None: retriever = VectorRetriever(driver, "vector-index-name", random_embedder) top_k = 5 effective_search_ratio = 2 results = retriever.search( query_text="Find me a book about Fremen", top_k=top_k, effective_search_ratio=effective_search_ratio, ) assert isinstance(results, RetrieverResult) assert len(results.items) == 5 for result in results.items: assert f"'{retriever._embedding_node_property}': None" in result.content assert isinstance(result, RetrieverResultItem) @pytest.mark.usefixtures("setup_neo4j_for_retrieval") def test_vector_cypher_retriever_search_text( driver: Driver, random_embedder: Embedder ) -> None: retrieval_query = "MATCH (node)-[:AUTHORED_BY]->(author:Author) RETURN author.name" retriever = VectorCypherRetriever( driver, "vector-index-name", retrieval_query, random_embedder ) top_k = 5 effective_search_ratio = 2 results = retriever.search( query_text="Find me a book about Fremen", top_k=top_k, effective_search_ratio=effective_search_ratio, ) assert isinstance(results, RetrieverResult) assert len(results.items) == 5 for record in results.items: assert isinstance(record, RetrieverResultItem) assert "author.name" in record.content @pytest.mark.usefixtures("setup_neo4j_for_retrieval") def test_vector_retriever_search_vector(driver: Driver) -> None: retriever = VectorRetriever(driver, "vector-index-name") top_k = 5 effective_search_ratio = 2 results = retriever.search( query_vector=[1.0 for _ in range(1536)], top_k=top_k, effective_search_ratio=effective_search_ratio, ) assert isinstance(results, RetrieverResult) assert len(results.items) == 5 for result in results.items: assert f"'{retriever._embedding_node_property}': None" in result.content assert isinstance(result, RetrieverResultItem) @pytest.mark.usefixtures("setup_neo4j_for_retrieval") def test_vector_cypher_retriever_search_vector(driver: Driver) -> None: retrieval_query = "MATCH (node)-[:AUTHORED_BY]->(author:Author) RETURN author.name" retriever = VectorCypherRetriever(driver, "vector-index-name", retrieval_query) top_k = 5 effective_search_ratio = 2 results = retriever.search( query_vector=[1.0 for _ in range(1536)], top_k=top_k, effective_search_ratio=effective_search_ratio, ) assert isinstance(results, RetrieverResult) assert len(results.items) == 5 for record in results.items: assert isinstance(record, RetrieverResultItem) assert "author.name" in record.content @pytest.mark.usefixtures("setup_neo4j_for_retrieval") def test_vector_retriever_return_properties(driver: Driver) -> None: properties = ["name", "age"] retriever = VectorRetriever( driver, "vector-index-name", return_properties=properties, ) top_k = 5 results = retriever.search( query_vector=[1.0 for _ in range(1536)], top_k=top_k, ) assert isinstance(results, RetrieverResult) assert len(results.items) == 5 for result in results.items: assert isinstance(result, RetrieverResultItem) @pytest.mark.usefixtures("setup_neo4j_for_retrieval") def test_vector_retriever_filters(driver: Driver) -> None: retriever = VectorRetriever( driver, "vector-index-name", ) top_k = 2 results = retriever.search( query_vector=[1.0 for _ in range(1536)], filters={"int_property": {"$gt": 2}}, top_k=top_k, ) assert isinstance(results, RetrieverResult) assert len(results.items) == 2 for result in results.items: assert isinstance(result, RetrieverResultItem) # assert result.node["int_property"] > 2