starting admin work

This commit is contained in:
2025-06-28 02:55:17 -05:00
parent 13d56066ab
commit adbb3250ad
11 changed files with 205 additions and 89 deletions

289
docs/LineageCheck.md Normal file
View File

@ -0,0 +1,289 @@
# 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!