Files
natureinpots_community/docs/LineageCheck.md
2025-06-28 02:55:17 -05:00

290 lines
7.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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:
```cypher
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:
```cypher
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:
```cypher
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:
```cypher
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:
```cypher
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:
```cypher
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:
```cypher
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:
```cypher
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:
```cypher
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:
```cypher
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):
```cypher
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**:
```cypher
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):
```cypher
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:
```cypher
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:
```cypher
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:
```python
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:
```bash
pip install neo4j
```
* Adjust the `uri` and `auth` values to match your Neo4j setup.
---
## 11. Summary of Key Cypher Queries
* **List all plants (sample):**
```cypher
MATCH (p:Plant)
RETURN p.uuid AS uuid, p.name AS common_name
LIMIT 20;
```
* **List direct parent→child relationships:**
```cypher
MATCH (child:Plant)-[:LINEAGE]->(parent:Plant)
RETURN child.uuid AS child_uuid, parent.uuid AS parent_uuid;
```
* **List direct children of a parent:**
```cypher
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:**
```cypher
MATCH (child:Plant {uuid:"CHILD_UUID"})-[:LINEAGE]->(parent:Plant)
RETURN parent.uuid AS parent_uuid, parent.name AS parent_name;
```
* **Visualize parent + children subgraph:**
```cypher
MATCH subtree = (parent:Plant {uuid:"PARENT_UUID"})<-[:LINEAGE]-(child:Plant)
RETURN subtree;
```
* **Full ancestor chain for a child:**
```cypher
MATCH path = (c:Plant {uuid:"CHILD_UUID"})-[:LINEAGE*1..]->(anc:Plant)
RETURN path;
```
* **Full descendant tree for a parent:**
```cypher
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:
```cypher
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!