graphiti icon indicating copy to clipboard operation
graphiti copied to clipboard

Received notification from DBMS server, and no searched result while data in Neo4j

Open hanwsf opened this issue 1 year ago • 2 comments

Neo4j 5.26 using quickstart.py or from mcp server ingest both showing:

2025-04-14 12:49:05,579 - neo4j.notifications - WARNING - Received notification from DBMS server: {severity: WARNING} {code: Neo.ClientNotification.Statement.UnknownPropertyKeyWarning} {category: UNRECOGNIZED} {title: The provided property key is not in the database} {description: One of the property names in your query is not available in the database, make sure you didn't misspell it or that the label is available when you run this statement in your application (the missing property name is: content)} {position: line: 4, column: 18, offset: 143} for query: '\n MATCH (e:Episodic) WHERE e.valid_at <= $reference_time \n AND ($group_ids IS NULL) OR e.group_id in $group_ids\n RETURN e.content AS content,\n e.created_at AS created_at,\n e.valid_at AS valid_at,\n e.uuid AS uuid,\n e.group_id AS group_id,\n e.name AS name,\n e.source_description AS source_description,\n e.source AS source\n ORDER BY e.created_at DESC\n LIMIT $num_episodes\n '

After ingestion is done, data in Neo4j, search result is empty.

2025-04-14 21:10:45 - neo4j.notifications - WARNING - Received notification from DBMS server: {severity: WARNING} {code: Neo.ClientNotification.Statement.UnknownPropertyKeyWarning} {category: UNRECOGNIZED} {title: The provided property key is not in the database} {description: One of the property names in your query is not available in the database, make sure you didn't misspell it or that the label is available when you run this statement in your application (the missing property name is: episodes)} {position: line: 16, column: 24, offset: 708} for query: '\n CALL db.index.fulltext.queryRelationships("edge_name_and_fact", $query, {limit: $limit}) \n YIELD relationship AS rel, score\n MATCH (:Entity)-[r:RELATES_TO]->(:Entity)\n WHERE r.group_id IN $group_ids\nWITH r, score, startNode(r) AS n, endNode(r) AS m\n RETURN\n r.uuid AS uuid,\n r.group_id AS group_id,\n n.uuid AS source_node_uuid,\n m.uuid AS target_node_uuid,\n r.created_at AS created_at,\n r.name AS name,\n r.fact AS fact,\n r.fact_embedding AS fact_embedding,\n r.episodes AS episodes,\n r.expired_at AS expired_at,\n r.valid_at AS valid_at,\n r.invalid_at AS invalid_at\n ORDER BY score DESC LIMIT $limit\n '

Search Results: No results found in the initial search to use as center node.

Image

Image

hanwsf avatar Apr 14 '25 13:04 hanwsf

What version of Graphiti are you using? Have you tried running graphiti.build_indices_and_constraints()

prasmussen15 avatar Apr 15 '25 01:04 prasmussen15

What version of Graphiti are you using? Have you tried running graphiti.build_indices_and_constraints()

graphiti-core 0.9.6

Yes. Code as: import asyncio import json import logging import os from datetime import datetime, timezone from logging import INFO

from dotenv import load_dotenv

from graphiti_core import Graphiti from graphiti_core.nodes import EpisodeType from graphiti_core.search.search_config_recipes import NODE_HYBRID_SEARCH_RRF from graphiti_core.llm_client.openai_generic_client import OpenAIGenericClient, LLMConfig from graphiti_core.embedder.openai import OpenAIEmbedder, OpenAIEmbedderConfig

#################################################

CONFIGURATION

#################################################

Set up logging and environment variables for

connecting to Neo4j database

#################################################

Configure logging

logging.basicConfig( level=INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S', ) logger = logging.getLogger(name)

load_dotenv()

Neo4j connection parameters

Make sure Neo4j Desktop is running with a local DBMS started

neo4j_uri = os.environ.get('NEO4J_URI', 'bolt://localhost:7687') neo4j_user = os.environ.get('NEO4J_USER', 'neo4j') neo4j_password = os.environ.get('NEO4J_PASSWORD', 'demodemo')

if not neo4j_uri or not neo4j_user or not neo4j_password: raise ValueError('NEO4J_URI, NEO4J_USER, and NEO4J_PASSWORD must be set')

llm_config = LLMConfig( api_key="empty", base_url="http://localhost:11434/v1/", model="qwen2.5:7b" ) llm_client = OpenAIGenericClient(config=llm_config)

embedder_config = OpenAIEmbedderConfig( api_key="empty", base_url="http://localhost:11434/v1/", embedding_model="bge-m3:latest" ) embedder = OpenAIEmbedder(config=embedder_config)

async def main(): ################################################# # INITIALIZATION ################################################# # Connect to Neo4j and set up Graphiti indices # This is required before using other Graphiti # functionality #################################################

# Initialize Graphiti with Neo4j connection
graphiti = Graphiti(
    neo4j_uri,
    neo4j_user,
    neo4j_password,
    llm_client=llm_client,
    embedder=embedder
)

try:
    await graphiti.build_indices_and_constraints(delete_existing=True)

    # Initialize the graph database with graphiti's indices. This only needs to be done once.
    await graphiti.build_indices_and_constraints()

    #################################################
    # ADDING EPISODES
    #################################################
    # Episodes are the primary units of information
    # in Graphiti. They can be text or structured JSON
    # and are automatically processed to extract entities
    # and relationships.
    #################################################

    # Example: Add Episodes
    # Episodes list containing both text and JSON episodes
    episodes = [
        {
            'content': 'Kamala Harris is the Attorney General of California. She was previously '
            'the district attorney for San Francisco.',
            'type': EpisodeType.text,
            'description': 'podcast transcript',
        },
        {
            'content': 'As AG, Harris was in office from January 3, 2011 – January 3, 2017',
            'type': EpisodeType.text,
            'description': 'podcast transcript',
        },
        {
            'content': {
                'name': 'Gavin Newsom',
                'position': 'Governor',
                'state': 'California',
                'previous_role': 'Lieutenant Governor',
                'previous_location': 'San Francisco',
            },
            'type': EpisodeType.json,
            'description': 'podcast metadata',
        },
        {
            'content': {
                'name': 'Gavin Newsom',
                'position': 'Governor',
                'term_start': 'January 7, 2019',
                'term_end': 'Present',
            },
            'type': EpisodeType.json,
            'description': 'podcast metadata',
        },
    ]

    # Add episodes to the graph and generate embeddings
    print("\nAdding episodes and generating embeddings...")
    for i, episode in enumerate(episodes):
        try:
            result = await graphiti.add_episode(
                name=f'Freakonomics Radio {i}',
                episode_body=episode['content']
                if isinstance(episode['content'], str)
                else json.dumps(episode['content']),
                source=episode['type'],
                source_description=episode['description'],
                reference_time=datetime.now(timezone.utc)
            )
            print(f'Added episode: Freakonomics Radio {i} ({episode["type"].value})')
        except Exception as e:
            logger.error(f"Failed to add episode {i}: {e}")

    async with graphiti.driver.session() as session:
        result = await session.run("MATCH (n:Entity) RETURN count(n) as count")
        record = await result.single()
        node_count = record["count"]
        print(f": {node_count}")

        result = await session.run("MATCH (n:Entity) WHERE n.name_embedding IS NOT NULL RETURN count(n) as count")
        record = await result.single()
        embedding_count = record["count"]
        print(f" {embedding_count}")

    if node_count > 0 and embedding_count == 0:
        async with graphiti.driver.session() as session:
            result = await session.run("MATCH (n:Entity) RETURN n.uuid as uuid, n.name as name")
            nodes = await result.data()
            
            for node in nodes:
                embedding = await graphiti.embedder.create(input_data=[node["name"]])
                await session.run(
                    "MATCH (n:Entity {uuid: $uuid}) SET n.name_embedding = $embedding",
                    uuid=node["uuid"],
                    embedding=embedding
                )

    print("\n searching...")

    #################################################
    # BASIC SEARCH
    #################################################
    # The simplest way to retrieve relationships (edges)
    # from Graphiti is using the search method, which
    # performs a hybrid search combining semantic
    # similarity and BM25 text retrieval.
    #################################################

    # Perform a hybrid search combining semantic similarity and BM25 retrieval
    print("\nSearching for: 'Who was the California Attorney General?'")
    results = await graphiti.search('Who was the California Attorney General?')

    # Print search results
    print('\nSearch Results:')
    for result in results:
        print(f'UUID: {result.uuid}')
        print(f'Fact: {result.fact}')
        if hasattr(result, 'valid_at') and result.valid_at:
            print(f'Valid from: {result.valid_at}')
        if hasattr(result, 'invalid_at') and result.invalid_at:
            print(f'Valid until: {result.invalid_at}')
        print('---')

    #################################################
    # CENTER NODE SEARCH
    #################################################
    # For more contextually relevant results, you can
    # use a center node to rerank search results based
    # on their graph distance to a specific node
    #################################################

    # Use the top search result's UUID as the center node for reranking
    if results and len(results) > 0:
        # Get the source node UUID from the top result
        center_node_uuid = results[0].source_node_uuid

        print('\nReranking search results based on graph distance:')
        print(f'Using center node UUID: {center_node_uuid}')

        reranked_results = await graphiti.search(
            'Who was the California Attorney General?', center_node_uuid=center_node_uuid
        )

        # Print reranked search results
        print('\nReranked Search Results:')
        for result in reranked_results:
            print(f'UUID: {result.uuid}')
            print(f'Fact: {result.fact}')
            if hasattr(result, 'valid_at') and result.valid_at:
                print(f'Valid from: {result.valid_at}')
            if hasattr(result, 'invalid_at') and result.invalid_at:
                print(f'Valid until: {result.invalid_at}')
            print('---')
    else:
        print('No results found in the initial search to use as center node.')

    #################################################
    # NODE SEARCH USING SEARCH RECIPES
    #################################################
    # Graphiti provides predefined search recipes
    # optimized for different search scenarios.
    # Here we use NODE_HYBRID_SEARCH_RRF for retrieving
    # nodes directly instead of edges.
    #################################################

    # Example: Perform a node search using _search method with standard recipes
    print(
        '\nPerforming node search using _search method with standard recipe NODE_HYBRID_SEARCH_RRF:'
    )

    # Use a predefined search configuration recipe and modify its limit
    node_search_config = NODE_HYBRID_SEARCH_RRF.model_copy(deep=True)
    node_search_config.limit = 5  # Limit to 5 results

    # Execute the node search
    node_search_results = await graphiti._search(
        query='California Governor',
        config=node_search_config,
    )

    # Print node search results
    print('\nNode Search Results:')
    for node in node_search_results.nodes:
        print(f'Node UUID: {node.uuid}')
        print(f'Node Name: {node.name}')
        node_summary = node.summary[:100] + '...' if len(node.summary) > 100 else node.summary
        print(f'Content Summary: {node_summary}')
        print(f'Node Labels: {", ".join(node.labels)}')
        print(f'Created At: {node.created_at}')
        if hasattr(node, 'attributes') and node.attributes:
            print('Attributes:')
            for key, value in node.attributes.items():
                print(f'  {key}: {value}')
        print('---')

finally:
    #################################################
    # CLEANUP
    #################################################
    # Always close the connection to Neo4j when
    # finished to properly release resources
    #################################################

    # Close the connection
    await graphiti.close()
    print('\nConnection closed')

if name == 'main': asyncio.run(main())

hanwsf avatar Apr 15 '25 09:04 hanwsf

I occasionally get his error as well.

Received notification from DBMS server: {severity: WARNING} {code: Neo.ClientNotification.Statement.UnknownLabelWarning} {category: UNRECOGNIZED} {title: The provided label is not in the database.} {description: One of the labels in your query is not available in the database, make sure you didn't misspell it or that the label is available when you run this statement in your application (the missing label name is: Preference)} {position: line: 3, column: 44, offset: 69} for query: '\n MATCH (n:Entity)\n WHERE n.group_id IS NOT NULL AND n:Preference\n WITH n, vector.similarity.cosine(n.name_embedding, $search_vector) AS score\n WHERE score > $min_score\n RETURN\n n.uuid As uuid, \n
n.name AS name,\n n.group_id AS group_id,\n n.created_at AS created_at, \n n.summary AS summary,\n labels(n) AS labels,\n properties(n) AS attributes\n \n ORDER BY score DESC\n LIMIT $limit\n

Basically, n:Preference is not a label.

I'm using v0.12.0 and my Neo4j version is 5.26.7 LLM = gpt-4.1-mini

codematrix avatar Jun 17 '25 21:06 codematrix

@hanwsf Is this still an issue? Please confirm within 14 days or this issue will be closed.

claude[bot] avatar Oct 03 '25 00:10 claude[bot]

@hanwsf Is this still an issue? Please confirm within 14 days or this issue will be closed.

claude[bot] avatar Oct 20 '25 00:10 claude[bot]

@hanwsf Is this still an issue? Please confirm within 14 days or this issue will be closed.

claude[bot] avatar Oct 22 '25 00:10 claude[bot]

@hanwsf Is this still an issue? Please confirm within 14 days or this issue will be closed.

claude[bot] avatar Oct 29 '25 00:10 claude[bot]

@hanwsf Is this still an issue? Please confirm within 14 days or this issue will be closed.

claude[bot] avatar Nov 17 '25 00:11 claude[bot]