Files
AI/참고/neo4j-graphrag-python-main/tests/e2e/test_indexes_e2e.py

267 lines
9.7 KiB
Python
Raw Normal View History

2026-05-12 19:40:31 +09:00
# 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 neo4j
import pytest
from neo4j_graphrag.indexes import (
retrieve_fulltext_index_info,
retrieve_vector_index_info,
upsert_vectors,
)
from neo4j_graphrag.types import EntityType
@pytest.mark.usefixtures("setup_neo4j_for_retrieval")
def test_retrieve_vector_index_info_happy_path(driver: neo4j.Driver) -> None:
index_info = retrieve_vector_index_info(
driver=driver,
index_name="vector-index-name",
label_or_type="Document",
embedding_property="vectorProperty",
)
assert index_info is not None
index_name = index_info.get("name")
assert index_name == "vector-index-name"
index_type = index_info.get("type")
assert index_type == "VECTOR"
labels_or_types = index_info.get("labelsOrTypes")
assert labels_or_types == ["Document"]
properties = index_info.get("properties")
assert properties == ["vectorProperty"]
entity_type = index_info.get("entityType")
assert entity_type == "NODE"
options = index_info.get("options")
assert isinstance(options, dict)
index_config = options.get("indexConfig")
assert isinstance(index_config, dict)
embedding_dimension = index_config.get("vector.dimensions")
assert isinstance(embedding_dimension, int)
assert embedding_dimension == 1536
@pytest.mark.usefixtures("setup_neo4j_for_retrieval")
def test_retrieve_vector_index_info_no_index_name(driver: neo4j.Driver) -> None:
index_info = retrieve_vector_index_info(
driver=driver,
index_name="",
label_or_type="Document",
embedding_property="vectorProperty",
)
assert index_info is not None
index_name = index_info.get("name")
assert index_name == "vector-index-name"
index_type = index_info.get("type")
assert index_type == "VECTOR"
labels_or_types = index_info.get("labelsOrTypes")
assert labels_or_types == ["Document"]
properties = index_info.get("properties")
assert properties == ["vectorProperty"]
entity_type = index_info.get("entityType")
assert entity_type == "NODE"
options = index_info.get("options")
assert isinstance(options, dict)
index_config = options.get("indexConfig")
assert isinstance(index_config, dict)
embedding_dimension = index_config.get("vector.dimensions")
assert isinstance(embedding_dimension, int)
assert embedding_dimension == 1536
@pytest.mark.usefixtures("setup_neo4j_for_retrieval")
def test_retrieve_vector_index_info_no_label_or_property(driver: neo4j.Driver) -> None:
index_info = retrieve_vector_index_info(
driver=driver,
index_name="vector-index-name",
label_or_type="",
embedding_property="",
)
assert index_info is not None
index_name = index_info.get("name")
assert index_name == "vector-index-name"
index_type = index_info.get("type")
assert index_type == "VECTOR"
labels_or_types = index_info.get("labelsOrTypes")
assert labels_or_types == ["Document"]
properties = index_info.get("properties")
assert properties == ["vectorProperty"]
entity_type = index_info.get("entityType")
assert entity_type == "NODE"
options = index_info.get("options")
assert isinstance(options, dict)
index_config = options.get("indexConfig")
assert isinstance(index_config, dict)
embedding_dimension = index_config.get("vector.dimensions")
assert isinstance(embedding_dimension, int)
assert embedding_dimension == 1536
@pytest.mark.usefixtures("setup_neo4j_for_retrieval")
def test_retrieve_vector_index_info_wrong_info(driver: neo4j.Driver) -> None:
index_info = retrieve_vector_index_info(
driver=driver,
index_name="err",
label_or_type="err",
embedding_property="err",
)
assert index_info is None
@pytest.mark.usefixtures("setup_neo4j_for_retrieval")
def test_retrieve_fulltext_index_info_happy_path(driver: neo4j.Driver) -> None:
index_info = retrieve_fulltext_index_info(
driver=driver,
index_name="fulltext-index-name",
label_or_type="Document",
text_properties=["short_text_property"],
)
assert index_info is not None
index_name = index_info.get("name")
assert index_name == "fulltext-index-name"
index_type = index_info.get("type")
assert index_type == "FULLTEXT"
labels_or_types = index_info.get("labelsOrTypes")
assert labels_or_types == ["Document"]
properties = index_info.get("properties")
assert properties == ["short_text_property"]
entity_type = index_info.get("entityType")
assert entity_type == "NODE"
@pytest.mark.usefixtures("setup_neo4j_for_retrieval")
def test_retrieve_fulltext_index_info_no_index_name(driver: neo4j.Driver) -> None:
index_info = retrieve_fulltext_index_info(
driver=driver,
index_name="",
label_or_type="Document",
text_properties=["short_text_property"],
)
assert index_info is not None
index_name = index_info.get("name")
assert index_name == "fulltext-index-name"
index_type = index_info.get("type")
assert index_type == "FULLTEXT"
labels_or_types = index_info.get("labelsOrTypes")
assert labels_or_types == ["Document"]
properties = index_info.get("properties")
assert properties == ["short_text_property"]
entity_type = index_info.get("entityType")
assert entity_type == "NODE"
@pytest.mark.usefixtures("setup_neo4j_for_retrieval")
def test_retrieve_fulltext_index_info_no_label_or_properties(
driver: neo4j.Driver,
) -> None:
index_info = retrieve_fulltext_index_info(
driver=driver,
index_name="fulltext-index-name",
label_or_type="",
text_properties=[""],
)
assert index_info is not None
index_name = index_info.get("name")
assert index_name == "fulltext-index-name"
index_type = index_info.get("type")
assert index_type == "FULLTEXT"
labels_or_types = index_info.get("labelsOrTypes")
assert labels_or_types == ["Document"]
properties = index_info.get("properties")
assert properties == ["short_text_property"]
entity_type = index_info.get("entityType")
assert entity_type == "NODE"
@pytest.mark.usefixtures("setup_neo4j_for_retrieval")
def test_retrieve_fulltext_index_info_wrong_info(driver: neo4j.Driver) -> None:
index_info = retrieve_fulltext_index_info(
driver=driver,
index_name="err",
label_or_type="err",
text_properties=[""],
)
assert index_info is None
def test_upsert_vectors_on_nodes(driver: neo4j.Driver) -> None:
driver.execute_query("MATCH (n) DETACH DELETE n;")
result = driver.execute_query(
"CREATE (p:Character {name: 'Paul Atreides'}), "
"(v:Character {name: 'Vladimir Harkonnen'}) "
"RETURN [elementId(p), elementId(v)] AS ids"
)
ids = result.records[0]["ids"]
assert len(ids) == 2
upsert_vectors(
driver=driver,
ids=ids,
embedding_property="embedding",
embeddings=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]],
entity_type=EntityType.NODE,
)
result = driver.execute_query(
"MATCH (c:Character) RETURN "
"elementId(c) as id, c.name as name, c.embedding as embedding"
)
records = [r.data() for r in result.records]
records_sorted = sorted(records, key=lambda x: x["id"])
expected_records = [
{"id": ids[0], "name": "Paul Atreides", "embedding": [1.0, 2.0, 3.0]},
{"id": ids[1], "name": "Vladimir Harkonnen", "embedding": [4.0, 5.0, 6.0]},
]
expected_records_sorted = sorted(expected_records, key=lambda x: x["id"])
assert records_sorted == expected_records_sorted
def test_upsert_vectors_on_relationships(driver: neo4j.Driver) -> None:
driver.execute_query("MATCH (n) DETACH DELETE n;")
result = driver.execute_query(
"CREATE (:Character {name: 'Paul Atreides'})-[a:IS_MEMBER_OF]->(:House {name: 'Atreides'}), "
"(:Character {name: 'Vladimir Harkonnen'})-[h:IS_MEMBER_OF]->(:House {name: 'Harkonnen'}) "
"RETURN [elementId(a), elementId(h)] AS ids"
)
ids = result.records[0]["ids"]
assert len(ids) == 2
upsert_vectors(
driver=driver,
ids=ids,
embedding_property="embedding",
embeddings=[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0]],
entity_type=EntityType.RELATIONSHIP,
)
result = driver.execute_query(
"MATCH (c:Character)-[r:IS_MEMBER_OF]->(h:House) RETURN "
"type(r) AS type, elementId(r) AS id, r.embedding AS embedding, "
"c.name as character, h.name AS house"
)
records = [r.data() for r in result.records]
records_sorted = sorted(records, key=lambda x: x["id"])
expected_records = [
{
"type": "IS_MEMBER_OF",
"id": ids[0],
"embedding": [1.0, 2.0, 3.0],
"character": "Paul Atreides",
"house": "Atreides",
},
{
"type": "IS_MEMBER_OF",
"id": ids[1],
"embedding": [4.0, 5.0, 6.0],
"character": "Vladimir Harkonnen",
"house": "Harkonnen",
},
]
expected_records_sorted = sorted(expected_records, key=lambda x: x["id"])
assert records_sorted == expected_records_sorted