Files
natureinpots_community/LineageCheck.md
2025-06-06 02:00:05 -05:00

7.7 KiB
Raw Blame History

Neo4j Lineage Verification Guide

Use this guide to confirm that your plants and LINEAGE relationships have been imported correctly into Neo4j. Save this file as neo4j_lineage_check.md for future reference.


1. Open the Neo4j Browser

  1. Ensure Neo4j is running. In a DockerCompose setup, Neo4j is typically exposed at:

    http://localhost:7474
    
  2. Log in with your Neo4j credentials (e.g., username neo4j, password as configured).

Once logged in, you can execute Cypher commands in the query pane on the left.


2. Verify That Your Plant Nodes Exist

Before checking relationships, confirm that nodes were created:

MATCH (p:Plant)
RETURN p.uuid AS uuid, p.name AS common_name
LIMIT 20;
  • This query will return up to 20 plant nodes with their uuid and name properties.
  • If you see your imported plants here, it means the nodes exist in the database.

3. Check Direct Parent→Child LINEAGE Pairs

To list all direct child→parent relationships:

MATCH (child:Plant)-[:LINEAGE]->(parent:Plant)
RETURN child.uuid AS child_uuid, parent.uuid AS parent_uuid
LIMIT 50;
  • Each row represents one (:Plant)-[:LINEAGE]->(:Plant) relationship.
  • child_uuid is the UUID of the child node, and parent_uuid is the UUID of its direct parent.

4. Look Up a Specific Plant by UUID or Name

If you know a particular plants UUID, you can confirm its properties:

MATCH (p:Plant {uuid: "YOUR_UUID_HERE"})
RETURN p.uuid AS uuid, p.name AS common_name, p.scientific_name AS sci_name;

Alternatively, if you only know the common name:

MATCH (p:Plant)
WHERE p.name = "Common Name Here"
RETURN p.uuid AS uuid, p.name AS common_name, p.scientific_name AS sci_name;

This helps you find the exact UUID or check that the name and scientific_name properties were stored correctly.


5. Show Children of a Given Parent

To list all direct children of a specific parent by UUID:

MATCH (parent:Plant {uuid: "PARENT_UUID_HERE"})<-[:LINEAGE]-(child:Plant)
RETURN child.uuid AS child_uuid, child.name AS child_name;
  • This returns every plant node that points to the specified parent_uuid via a LINEAGE relationship.

6. Visualize a Subtree Around One Node

To visualize a parent node and its children in graph form:

MATCH subtree = (parent:Plant {uuid: "PARENT_UUID_HERE"})<-[:LINEAGE]-(child:Plant)
RETURN subtree;
  • Switch to the “Graph” view in the Neo4j browser to see a node for the parent with arrows pointing to each child.

7. Walk the Full Ancestor Chain (MultiLevel)

If you want to see all ancestors of a given child, use a variablelength pattern:

MATCH path = (desc:Plant {uuid: "CHILD_UUID_HERE"})-[:LINEAGE*1..]->(anc:Plant)
RETURN path;
  • [:LINEAGE*1..] indicates “follow one or more consecutive LINEAGE relationships upward.”
  • In “Graph” view, Neo4j will display the entire chain from child → parent → grandparent → …

To return just the list of ancestor UUIDs:

MATCH (start:Plant {uuid: "CHILD_UUID_HERE"})-[:LINEAGE*1..]->(anc:Plant)
RETURN DISTINCT anc.uuid AS ancestor_uuid;

8. Show All Descendants of a Given Parent

To find all descendants (children, grandchildren, etc.) of a root node:

MATCH (root:Plant {uuid: "ROOT_UUID_HERE"})<-[:LINEAGE*]-(desc:Plant)
RETURN desc.uuid AS descendant_uuid, desc.name AS descendant_name;
  • The pattern [:LINEAGE*] (with no lower bound specified) matches zero or more hops.

  • To visualize the full descendant tree:

    MATCH subtree = (root:Plant {uuid: "ROOT_UUID_HERE"})<-[:LINEAGE*]-(desc:Plant)
    RETURN subtree;
    

    Then switch to “Graph” view.


9. Combining Queries for a Full WalkThrough

  1. List a few plants (to copy a known UUID):

    MATCH (p:Plant)
    RETURN p.uuid AS uuid, p.name AS common_name
    LIMIT 10;
    
  2. Pick one UUID (e.g. "2ee2e0e7-69de-4b8f-abfe-4ed973c3d760").

  3. Show its direct children:

    MATCH (p:Plant {uuid: "2ee2e0e7-69de-4b8f-abfe-4ed973c3d760"})<-[:LINEAGE]-(child:Plant)
    RETURN child.uuid AS child_uuid, child.name AS child_name;
    
  4. Show its parent (if any):

    MATCH (p:Plant {uuid: "8b1059c8-8dd3-487a-af19-1eb548788e87"})-[:LINEAGE]->(parent:Plant)
    RETURN parent.uuid AS parent_uuid, parent.name AS parent_name;
    
  5. Get the full ancestor chain of that child:

    MATCH path = (c:Plant {uuid: "8b1059c8-8dd3-487a-af19-1eb548788e87"})-[:LINEAGE*1..]->(anc:Plant)
    RETURN path;
    
  6. Get the full descendant tree of that parent:

    MATCH subtree = (root:Plant {uuid: "2ee2e0e7-69de-4b8f-abfe-4ed973c3d760"})<-[:LINEAGE*]-(desc:Plant)
    RETURN subtree;
    

10. Checking via Python (Optional)

If you prefer to script these checks using the Neo4j Bolt driver from Python, heres a quick example:

from neo4j import GraphDatabase

uri      = "bolt://localhost:7687"
auth     = ("neo4j", "your_password")
driver   = GraphDatabase.driver(uri, auth=auth)

def print_lineage(tx, plant_uuid):
    # Show direct parent
    result = tx.run(
        "MATCH (c:Plant {uuid:$u})-[:LINEAGE]->(p:Plant) "
        "RETURN p.uuid AS parent_uuid, p.name AS parent_name",
        u=plant_uuid
    )
    for row in result:
        print(f"Parent of {plant_uuid}: {row['parent_uuid']} ({row['parent_name']})")

    # Show all ancestors
    result2 = tx.run(
        "MATCH path = (c:Plant {uuid:$u})-[:LINEAGE*1..]->(anc:Plant) "
        "RETURN [n IN nodes(path) | n.uuid] AS all_uuids",
        u=plant_uuid
    )
    for row in result2:
        print("Ancestor chain UUIDs:", row["all_uuids"])

with driver.session() as session:
    session.read_transaction(print_lineage, "8b1059c8-8dd3-487a-af19-1eb548788e87")

driver.close()
  • Install neo4j Python package if needed:

    pip install neo4j
    
  • Adjust the uri and auth values to match your Neo4j setup.


11. Summary of Key Cypher Queries

  • List all plants (sample):

    MATCH (p:Plant)
    RETURN p.uuid AS uuid, p.name AS common_name
    LIMIT 20;
    
  • List direct parent→child relationships:

    MATCH (child:Plant)-[:LINEAGE]->(parent:Plant)
    RETURN child.uuid AS child_uuid, parent.uuid AS parent_uuid;
    
  • List direct children of a parent:

    MATCH (parent:Plant {uuid:"PARENT_UUID"})<-[:LINEAGE]-(child:Plant)
    RETURN child.uuid AS child_uuid, child.name AS child_name;
    
  • List direct parent of a child:

    MATCH (child:Plant {uuid:"CHILD_UUID"})-[:LINEAGE]->(parent:Plant)
    RETURN parent.uuid AS parent_uuid, parent.name AS parent_name;
    
  • Visualize parent + children subgraph:

    MATCH subtree = (parent:Plant {uuid:"PARENT_UUID"})<-[:LINEAGE]-(child:Plant)
    RETURN subtree;
    
  • Full ancestor chain for a child:

    MATCH path = (c:Plant {uuid:"CHILD_UUID"})-[:LINEAGE*1..]->(anc:Plant)
    RETURN path;
    
  • Full descendant tree for a parent:

    MATCH subtree = (root:Plant {uuid:"PARENT_UUID"})<-[:LINEAGE*]-(desc:Plant)
    RETURN subtree;
    

Usage Tips

  • Switch between “Table” and “Graph” views in the Neo4j Browser to see raw data vs. visual graph.

  • Use LIMIT when you only want a quick preview of results.

  • To filter by partial names, you can do:

    MATCH (p:Plant)
    WHERE toLower(p.name) CONTAINS toLower("baltic")
    RETURN p.uuid, p.name;
    
  • Remember to enclose string literals in double quotes ("...") and escape any internal quotes if needed.

Keep this guide handy for whenever you need to verify or debug your Neo4j lineage data!