#4462 Add Domain->System Relationship to Systems Engineering KG

#4462 Add Domain->System Relationship to Systems Engineering KG

#4462 I have a loop of domain names, and system names within each domain. Correct the following Cypher statements: """MERGE (d:Domain {name:'domain_name', label:'domain_name'})

MATCH (s:System {name:'system_name')

MERGE (d)-[:HAS_SYSTEM]->(s)""" 

There are two main issues with your current Cypher snippet that will cause syntax errors:

  1. The missing parenthesis: In your MATCH statement, you opened the node syntax with ( but forgot to close it before the brace, resulting in (s:System {name:'system_name'). It needs to be (s:System {name:'system_name'}).

  2. The MATCH and MERGE disconnect: If Cypher executes a MATCH that finds 0 results, the entire query execution stops right there. This means if a system doesn't exist yet, the final MERGE relationship will never be created. If your goal is to ensure the system exists and link it, you should use MERGE for the system as well.

Here are the corrected versions depending on how you want to handle missing systems.

Option 1: If the System might not exist yet (Recommended)

Use MERGE for both the domain and the system. This ensures that even if the system is new, Neo4j will create it and then link it to the domain.

MERGE (d:Domain {name: 'domain_name', label: 'domain_name'})
MERGE (s:System {name: 'system_name'})
MERGE (d)-[:HAS_SYSTEM]->(s)

Option 2: If the System must already exist

If you only want to create the relationship when the system already exists in your database (and do nothing if it doesn't), use the corrected MATCH statement:

MERGE (d:Domain {name: 'domain_name', label: 'domain_name'})
MATCH (s:System {name: 'system_name'})
MERGE (d)-[:HAS_SYSTEM]->(s)

💡 Performance Tip for Loops

Since you mentioned you are running this in a loop, passing domain_name and system_name as parameters (instead of hardcoded strings) will drastically speed up your execution. It allows Neo4j to reuse the query execution plan.

Your parameterized query would look like this:

MERGE (d:Domain {name: $domain_name, label: $domain_name})
MERGE (s:System {name: $system_name})
MERGE (d)-[:HAS_SYSTEM]->(s)


Provide the python code for the parameterized version where system must exist

Here is the Python code using the official neo4j driver.

Since you specified that the System must already exist, this code uses MATCH for the system. It also wraps the operation in a transaction function, which is the recommended best practice for handling connections and retries.

Python Code

from neo4j import GraphDatabase

# 1. Connection details
URI = "neo4j://localhost:7687"
AUTH = ("neo4j", "your_password")

# 2. Your loop data (Example)
data_loop = [
    {"domain": "finance.local", "system": "ledger_prod"},
    {"domain": "finance.local", "system": "billing_api"},
    {"domain": "hr.local", "system": "payroll_app"}, 
    {"domain": "hr.local", "system": "missing_system_xyz"} # If this doesn't exist, no relationship is made
]

# 3. Cypher Query (Parameterized)
# Uses MERGE for Domain, MATCH for System. If MATCH fails, the query gracefully skips.
query = """
MERGE (d:Domain {name: $domain_name, label: $domain_name})
WITH d
MATCH (s:System {name: $system_name})
MERGE (d)-[:HAS_SYSTEM]->(s)
"""

def link_domain_to_system(tx, domain_name, system_name):
    tx.run(query, domain_name=domain_name, system_name=system_name)

# 4. Execution
with GraphDatabase.driver(URI, auth=AUTH) as driver:
    with driver.session() as session:
        for item in data_loop:
            # execute_write automatically handles retries for transient errors
            session.execute_write(
                link_domain_to_system, 
                domain_name=item["domain"], 
                system_name=item["system"]
            )
            print(f"Processed: {item['domain']} -> {item['system']}")

print("Loop completed successfully!")

Why the WITH d was added to the query:

In standard Cypher, mixing MERGE and MATCH sequentially can sometimes confuse the compiler regarding cardonality. Adding WITH d acts as a clean pipe, passing the domain node into the MATCH clause cleanly and ensuring that if MATCH finds nothing, it safely stops for that specific loop iteration without breaking the script.


From <https://gemini.google.com/app/>  Google Gemini (3.5 Flash)

Comments

Popular posts from this blog

#2892 Example of ChatGPT o1 Prompt

#3679 Google Gemini 2.5 Pro: Create Python Application to View and Query Neo4j KG