Neo4j Plugin
Graph database operations with native Cypher query support for Neo4j.
#Installation
bash
pip install neo4j#Quick Start
python
from daita import Agent
from daita.plugins import neo4j
# Create Neo4j plugin
graph = neo4j(
uri="bolt://localhost:7687",
auth=("neo4j", "password")
)
# Agent uses graph database tools autonomously
agent = Agent(
name="Graph Analyst",
prompt="You are a graph database expert. Help users query and analyze graph data.",
tools=[graph]
)
await agent.start()
result = await agent.run("Find all people who know John Doe")
await agent.stop()#Direct Usage
The plugin can be used directly for programmatic graph operations:
python
from daita.plugins import neo4j
# Create connection
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Execute Cypher query
result = await graph.query("MATCH (n:Person) RETURN n LIMIT 10")
print(f"Found {result['count']} people")#Connection Parameters
python
neo4j(
uri: str = "bolt://localhost:7687",
auth: Optional[tuple] = None,
username: Optional[str] = None,
password: Optional[str] = None,
database: str = "neo4j",
**kwargs
)#Parameters
uri(str): Neo4j URI (bolt:// or neo4j://)auth(tuple): Tuple of (username, password)username(str): Username (alternative to auth tuple)password(str): Password (alternative to auth tuple)database(str): Database name (default: "neo4j")**kwargs: Additional neo4j driver parameters
#Node Operations
#Create Nodes
Create nodes with labels and properties:
python
from daita.plugins import neo4j
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Create person node
result = await graph.create_node(
label="Person",
properties={"name": "Alice", "age": 30, "email": "alice@example.com"}
)
print(f"Created node: {result['node']}")#Find Nodes
Find nodes by label and properties:
python
from daita.plugins import neo4j
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Find all people named Alice
result = await graph.find_nodes(
label="Person",
properties={"name": "Alice"},
limit=10
)
print(f"Found {result['count']} nodes")
for node in result['nodes']:
print(f" - {node}")#Delete Nodes
Delete nodes and their relationships:
python
from daita.plugins import neo4j
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Delete person
await graph.delete_node(
label="Person",
properties={"name": "Alice"}
)#Relationship Operations
#Create Relationships
Create relationships between nodes:
python
from daita.plugins import neo4j
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Create friendship
result = await graph.create_relationship(
from_label="Person",
from_properties={"name": "Alice"},
to_label="Person",
to_properties={"name": "Bob"},
relationship_type="KNOWS",
relationship_properties={"since": "2020", "strength": "strong"}
)
print(f"Created relationship: {result['relationship_type']}")#Get Neighbors
Find neighboring nodes:
python
from daita.plugins import neo4j
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Get all friends of Alice
result = await graph.get_neighbors(
label="Person",
properties={"name": "Alice"},
relationship_type="KNOWS",
direction="outgoing"
)
print(f"Found {result['count']} neighbors")
for neighbor in result['neighbors']:
print(f" - {neighbor['node']['name']}")Direction Options:
outgoing- Follow outgoing relationshipsincoming- Follow incoming relationshipsboth- Follow relationships in both directions
#Path Operations
#Find Shortest Path
Find shortest path between two nodes:
python
from daita.plugins import neo4j
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Find path from Alice to Bob
result = await graph.find_path(
from_label="Person",
from_properties={"name": "Alice"},
to_label="Person",
to_properties={"name": "Bob"},
max_length=5
)
if result['found']:
print(f"Path length: {result['path_length']}")
print(f"Path: {result['path']}")
else:
print("No path found")#Cypher Queries
#Execute Custom Queries
Run any Cypher query directly:
python
from daita.plugins import neo4j
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Complex query with parameters
result = await graph.query(
cypher="""
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
WHERE c.industry = $industry
RETURN p.name, c.name
LIMIT $limit
""",
parameters={"industry": "Technology", "limit": 10}
)
for record in result['records']:
print(f"{record['p.name']} works at {record['c.name']}")#Pattern Matching
python
from daita.plugins import neo4j
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Find complex patterns
result = await graph.query("""
MATCH (a:Person)-[:KNOWS]->(b:Person)-[:KNOWS]->(c:Person)
WHERE a.name = 'Alice' AND NOT (a)-[:KNOWS]->(c)
RETURN c.name AS potential_friend
""")
print("Potential friends (friends of friends):")
for record in result['records']:
print(f" - {record['potential_friend']}")#Using with Agents
The Neo4j plugin exposes graph operations as tools that agents can use autonomously:
python
from daita import Agent
from daita.plugins import neo4j
# Create Neo4j connection
graph = neo4j(
uri="bolt://localhost:7687",
username="neo4j",
password="password",
database="social"
)
# Agent with graph tools
agent = Agent(
name="Social Graph Analyst",
prompt="You are a social network analyst. Help users explore and analyze social graphs.",
llm_provider="openai",
model="gpt-4",
tools=[graph]
)
await agent.start()
# Agent autonomously uses graph tools
result = await agent.run("""
Find all people in the Technology industry who know Alice.
Then find the shortest path between Alice and the CEO of TechCorp.
""")
print(result)
await agent.stop()#Available Tools
The Neo4j plugin exposes these tools to agents:
| Tool | Description | Parameters |
|---|---|---|
| query_graph | Execute Cypher query | cypher, parameters |
| create_node | Create node | label, properties |
| create_relationship | Create relationship | from_label, from_properties, to_label, to_properties, relationship_type |
| find_nodes | Find nodes | label, properties, limit |
| find_path | Find shortest path | from_label, from_properties, to_label, to_properties, max_length |
| get_neighbors | Get neighboring nodes | label, properties, relationship_type, direction |
| delete_node | Delete node | label, properties |
#Connection Management
#Context Manager
Use context managers for automatic cleanup:
python
from daita.plugins import neo4j
async with neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password")) as graph:
# Connection automatically managed
await graph.query("MATCH (n) RETURN n LIMIT 1")
# Connection automatically closed#Manual Management
python
from daita.plugins import neo4j
graph = neo4j(uri="bolt://localhost:7687", auth=("neo4j", "password"))
await graph.connect()
try:
result = await graph.query("MATCH (n) RETURN n LIMIT 10")
finally:
await graph.disconnect()#Best Practices
Connection:
- Use context managers for automatic cleanup
- Configure appropriate timeouts for complex queries
- Use connection pooling for high-throughput applications
Queries:
- Use parameterized queries to prevent injection
- Add appropriate indexes for performance
- Limit result sets to avoid memory issues
Security:
- Store credentials securely, never hardcode
- Use read-only accounts when possible
- Limit database access by role
Performance:
- Create indexes on frequently queried properties
- Use LIMIT clauses to restrict result sizes
- Profile queries using Neo4j's EXPLAIN and PROFILE
#Troubleshooting
| Issue | Solution |
|---|---|
neo4j driver not installed | pip install neo4j |
| Connection timeout | Check Neo4j is running, verify URI |
| Authentication failed | Verify username/password, check database |
| Query timeout | Optimize query, add indexes, increase timeout |
#Next Steps
- Catalog Plugin - Discover database schemas
- Lineage Plugin - Track data flows
- Workflows - Use Neo4j in multi-agent workflows