| import json
|
| import re
|
| from neo4j import GraphDatabase
|
|
|
|
|
| def sanitize_string(input_str, max_length=255):
|
| """
|
| Process the input string to ensure it meets the database requirements.
|
| """
|
|
|
| input_str = re.sub(r'[^a-zA-Z0-9_]', '_', input_str)
|
|
|
|
|
| if input_str[0].isdigit():
|
| input_str = 'num' + input_str
|
|
|
|
|
| if len(input_str) > max_length:
|
| input_str = input_str[:max_length]
|
|
|
| return input_str
|
|
|
|
|
| def generate_cypher_statements(data):
|
| """
|
| Generates Cypher query statements based on the provided JSON data.
|
| """
|
| cypher_statements = []
|
| parsed_data = json.loads(data)
|
|
|
| def create_statement(triple):
|
| head = triple.get("head")
|
| head_type = triple.get("head_type")
|
| relation = triple.get("relation")
|
| relation_type = triple.get("relation_type")
|
| tail = triple.get("tail")
|
| tail_type = triple.get("tail_type")
|
|
|
|
|
| head_type_safe = sanitize_string(head_type) if head_type else None
|
|
|
| relation_type_safe = sanitize_string(relation_type) if relation_type else None
|
|
|
| tail_type_safe = sanitize_string(tail_type) if tail_type else None
|
|
|
| statement = ""
|
| if head:
|
| if head_type_safe:
|
| statement += f'MERGE (a:{head_type_safe} {{name: "{head}"}}) '
|
| else:
|
| statement += f'MERGE (a:UNTYPED {{name: "{head}"}}) '
|
| if tail:
|
| if tail_type_safe:
|
| statement += f'MERGE (b:{tail_type_safe} {{name: "{tail}"}}) '
|
| else:
|
| statement += f'MERGE (b:UNTYPED {{name: "{tail}"}}) '
|
| if relation:
|
| if head and tail:
|
| if relation_type_safe:
|
| statement += f'MERGE (a)-[:{relation_type_safe} {{name: "{relation}"}}]->(b);'
|
| else:
|
| statement += f'MERGE (a)-[:UNTYPED {{name: "{relation}"}}]->(b);'
|
| else:
|
| statement += ';' if statement != "" else ''
|
| else:
|
| if relation_type_safe:
|
| statement += f'MERGE (a)-[:{relation_type_safe} {{name: "{relation_type_safe}"}}]->(b);'
|
| else:
|
| statement += ';' if statement != "" else ''
|
| return statement
|
|
|
| if "triple_list" in parsed_data:
|
| for triple in parsed_data["triple_list"]:
|
| cypher_statements.append(create_statement(triple))
|
| else:
|
| cypher_statements.append(create_statement(parsed_data))
|
|
|
| return cypher_statements
|
|
|
|
|
| def execute_cypher_statements(uri, user, password, cypher_statements):
|
| """
|
| Executes the generated Cypher query statements.
|
| """
|
| driver = GraphDatabase.driver(uri, auth=(user, password))
|
|
|
| with driver.session() as session:
|
| for statement in cypher_statements:
|
| session.run(statement)
|
| print(f"Executed: {statement}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| driver.close()
|
|
|
|
|
|
|
| if __name__ == "__main__":
|
|
|
| test_data = '''
|
| {
|
| "triple_list": [
|
| {
|
| "head": "J.K. Rowling",
|
| "head_type": "Person",
|
| "relation": "wrote",
|
| "relation_type": "Actions",
|
| "tail": "Fantastic Beasts and Where to Find Them",
|
| "tail_type": "Book"
|
| },
|
| {
|
| "head": "Fantastic Beasts and Where to Find Them",
|
| "head_type": "Book",
|
| "relation": "extra section of",
|
| "relation_type": "Affiliation",
|
| "tail": "Harry Potter Series",
|
| "tail_type": "Book"
|
| },
|
| {
|
| "head": "J.K. Rowling",
|
| "head_type": "Person",
|
| "relation": "wrote",
|
| "relation_type": "Actions",
|
| "tail": "Harry Potter Series",
|
| "tail_type": "Book"
|
| },
|
| {
|
| "head": "Harry Potter Series",
|
| "head_type": "Book",
|
| "relation": "create",
|
| "relation_type": "Actions",
|
| "tail": "Dumbledore",
|
| "tail_type": "Person"
|
| },
|
| {
|
| "head": "Fantastic Beasts and Where to Find Them",
|
| "head_type": "Book",
|
| "relation": "mention",
|
| "relation_type": "Actions",
|
| "tail": "Dumbledore",
|
| "tail_type": "Person"
|
| },
|
| {
|
| "head": "Voldemort",
|
| "head_type": "Person",
|
| "relation": "afrid",
|
| "relation_type": "Emotion",
|
| "tail": "Dumbledore",
|
| "tail_type": "Person"
|
| },
|
| {
|
| "head": "Voldemort",
|
| "head_type": "Person",
|
| "relation": "robs",
|
| "relation_type": "Actions",
|
| "tail": "the Elder Wand",
|
| "tail_type": "Weapon"
|
| },
|
| {
|
| "head": "the Elder Wand",
|
| "head_type": "Weapon",
|
| "relation": "belong to",
|
| "relation_type": "Affiliation",
|
| "tail": "Dumbledore",
|
| "tail_type": "Person"
|
| }
|
| ]
|
| }
|
| '''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| cypher_statements = generate_cypher_statements(test_data)
|
|
|
|
|
| for statement in cypher_statements:
|
| print(statement)
|
| print("\n")
|
|
|
|
|
| execute_cypher_statements(
|
| uri="neo4j://localhost:7687",
|
| user="your_username",
|
| password="your_password",
|
| cypher_statements=cypher_statements,
|
| )
|
|
|