starting admin work
This commit is contained in:
289
docs/LineageCheck.md
Normal file
289
docs/LineageCheck.md
Normal 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 Docker‐Compose 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 plant’s 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 (Multi‐Level)
|
||||
|
||||
If you want to see all ancestors of a given child, use a variable‐length 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 Walk‐Through
|
||||
|
||||
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, here’s 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!
|
Reference in New Issue
Block a user