Merge commit 'd803bfe2b1fe7f5e219e50ac20d6801a0a58ac75' as 'vendor/ruvector'
This commit is contained in:
34
vendor/ruvector/examples/docs/README.md
vendored
Normal file
34
vendor/ruvector/examples/docs/README.md
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
# RuVector Documentation
|
||||
|
||||
Additional documentation and usage guides.
|
||||
|
||||
## Contents
|
||||
|
||||
| File | Description |
|
||||
|------|-------------|
|
||||
| `graph-cli-usage.md` | Command-line interface for graph operations |
|
||||
| `graph_wasm_usage.html` | Interactive WASM graph demo |
|
||||
|
||||
## Graph CLI
|
||||
|
||||
The graph CLI provides command-line access to RuVector's graph features:
|
||||
|
||||
```bash
|
||||
ruvector-graph --help
|
||||
ruvector-graph query "MATCH (n) RETURN n LIMIT 10"
|
||||
ruvector-graph import data.json
|
||||
ruvector-graph export output.json
|
||||
```
|
||||
|
||||
See [graph-cli-usage.md](graph-cli-usage.md) for full documentation.
|
||||
|
||||
## WASM Demo
|
||||
|
||||
Open `graph_wasm_usage.html` in a browser to see an interactive demonstration of RuVector's WebAssembly graph capabilities.
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [Main Examples README](../README.md)
|
||||
- [Rust Examples](../rust/README.md)
|
||||
- [Node.js Examples](../nodejs/README.md)
|
||||
- [React + WASM](../wasm-react/README.md)
|
||||
467
vendor/ruvector/examples/docs/graph-cli-usage.md
vendored
Normal file
467
vendor/ruvector/examples/docs/graph-cli-usage.md
vendored
Normal file
@@ -0,0 +1,467 @@
|
||||
# RuVector Graph CLI - Usage Examples
|
||||
|
||||
This guide demonstrates practical usage of the RuVector graph database CLI commands.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### 1. Create a New Graph Database
|
||||
|
||||
```bash
|
||||
# Create with default settings
|
||||
ruvector graph create --path ./my-graph.db --name production
|
||||
|
||||
# Create with property indexing enabled
|
||||
ruvector graph create --path ./my-graph.db --name production --indexed
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
✓ Creating graph database at: ./my-graph.db
|
||||
Graph name: production
|
||||
Property indexing: enabled
|
||||
✓ Graph database created successfully!
|
||||
ℹ Use 'ruvector graph shell' to start interactive mode
|
||||
```
|
||||
|
||||
### 2. Execute Cypher Queries
|
||||
|
||||
```bash
|
||||
# Simple query
|
||||
ruvector graph query -b ./my-graph.db -q "MATCH (n:Person) RETURN n"
|
||||
|
||||
# Query with output format
|
||||
ruvector graph query -b ./my-graph.db -q "MATCH (n) RETURN n" --format json
|
||||
|
||||
# Show query execution plan
|
||||
ruvector graph query -b ./my-graph.db -q "MATCH (n)-[r]->(m) RETURN n, r, m" --explain
|
||||
```
|
||||
|
||||
**Note:** Use `-b` for database path (not `-d`, which is global debug flag)
|
||||
**Note:** Use `-q` for cypher query (not `-c`, which is global config flag)
|
||||
|
||||
### 3. Interactive Shell (REPL)
|
||||
|
||||
```bash
|
||||
# Start shell
|
||||
ruvector graph shell -b ./my-graph.db
|
||||
|
||||
# Start shell with multiline mode (queries end with semicolon)
|
||||
ruvector graph shell -b ./my-graph.db --multiline
|
||||
```
|
||||
|
||||
**Example Session:**
|
||||
```
|
||||
RuVector Graph Shell
|
||||
Database: ./my-graph.db
|
||||
Type :exit to exit, :help for help
|
||||
|
||||
cypher> CREATE (alice:Person {name: 'Alice', age: 30})
|
||||
✓ Query completed in 5.23ms
|
||||
|
||||
cypher> CREATE (bob:Person {name: 'Bob', age: 25})
|
||||
✓ Query completed in 3.12ms
|
||||
|
||||
cypher> MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
|
||||
... CREATE (a)-[:KNOWS {since: 2020}]->(b)
|
||||
✓ Query completed in 4.56ms
|
||||
|
||||
cypher> MATCH (n:Person) RETURN n.name, n.age
|
||||
+--------+-------+
|
||||
| name | age |
|
||||
+--------+-------+
|
||||
| Alice | 30 |
|
||||
| Bob | 25 |
|
||||
+--------+-------+
|
||||
|
||||
cypher> :exit
|
||||
✓ Goodbye!
|
||||
```
|
||||
|
||||
**Shell Commands:**
|
||||
- `:exit`, `:quit`, `:q` - Exit the shell
|
||||
- `:help`, `:h` - Show help
|
||||
- `:clear` - Clear query buffer
|
||||
|
||||
### 4. Import Graph Data
|
||||
|
||||
#### JSON Format
|
||||
|
||||
```bash
|
||||
ruvector graph import -b ./my-graph.db -i data.json --format json -g production
|
||||
```
|
||||
|
||||
**Example `data.json`:**
|
||||
```json
|
||||
{
|
||||
"nodes": [
|
||||
{
|
||||
"id": "1",
|
||||
"labels": ["Person"],
|
||||
"properties": {
|
||||
"name": "Alice",
|
||||
"age": 30,
|
||||
"city": "San Francisco"
|
||||
}
|
||||
},
|
||||
{
|
||||
"id": "2",
|
||||
"labels": ["Person"],
|
||||
"properties": {
|
||||
"name": "Bob",
|
||||
"age": 25,
|
||||
"city": "New York"
|
||||
}
|
||||
}
|
||||
],
|
||||
"relationships": [
|
||||
{
|
||||
"id": "r1",
|
||||
"type": "KNOWS",
|
||||
"startNode": "1",
|
||||
"endNode": "2",
|
||||
"properties": {
|
||||
"since": 2020,
|
||||
"closeness": 0.8
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### Cypher Format
|
||||
|
||||
```bash
|
||||
ruvector graph import -b ./my-graph.db -i init.cypher --format cypher
|
||||
```
|
||||
|
||||
**Example `init.cypher`:**
|
||||
```cypher
|
||||
CREATE (alice:Person {name: 'Alice', age: 30, city: 'SF'});
|
||||
CREATE (bob:Person {name: 'Bob', age: 25, city: 'NYC'});
|
||||
CREATE (carol:Person {name: 'Carol', age: 28, city: 'LA'});
|
||||
|
||||
MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
|
||||
CREATE (a)-[:KNOWS {since: 2020}]->(b);
|
||||
|
||||
MATCH (b:Person {name: 'Bob'}), (c:Person {name: 'Carol'})
|
||||
CREATE (b)-[:KNOWS {since: 2021}]->(c);
|
||||
```
|
||||
|
||||
#### CSV Format
|
||||
|
||||
```bash
|
||||
ruvector graph import -b ./my-graph.db -i nodes.csv --format csv
|
||||
```
|
||||
|
||||
**Example `nodes.csv`:**
|
||||
```csv
|
||||
id,labels,properties
|
||||
1,"[""Person""]","{""name"": ""Alice"", ""age"": 30}"
|
||||
2,"[""Person""]","{""name"": ""Bob"", ""age"": 25}"
|
||||
```
|
||||
|
||||
### 5. Export Graph Data
|
||||
|
||||
```bash
|
||||
# Export to JSON
|
||||
ruvector graph export -b ./my-graph.db -o backup.json --format json
|
||||
|
||||
# Export to Cypher statements
|
||||
ruvector graph export -b ./my-graph.db -o backup.cypher --format cypher
|
||||
|
||||
# Export to GraphML (for Gephi, Cytoscape, etc.)
|
||||
ruvector graph export -b ./my-graph.db -o graph.graphml --format graphml
|
||||
|
||||
# Export specific graph
|
||||
ruvector graph export -b ./my-graph.db -o prod-backup.json -g production
|
||||
```
|
||||
|
||||
### 6. Database Information
|
||||
|
||||
```bash
|
||||
# Basic info
|
||||
ruvector graph info -b ./my-graph.db
|
||||
|
||||
# Detailed statistics
|
||||
ruvector graph info -b ./my-graph.db --detailed
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Graph Database Statistics
|
||||
Database: ./my-graph.db
|
||||
Graphs: 1
|
||||
Total nodes: 1,234
|
||||
Total relationships: 5,678
|
||||
Node labels: 3
|
||||
Relationship types: 5
|
||||
|
||||
Storage Information:
|
||||
Store size: 45.2 MB
|
||||
Index size: 12.8 MB
|
||||
|
||||
Configuration:
|
||||
Cache size: 128 MB
|
||||
Page size: 4096 bytes
|
||||
```
|
||||
|
||||
### 7. Performance Benchmarks
|
||||
|
||||
```bash
|
||||
# Traverse benchmark
|
||||
ruvector graph benchmark -b ./my-graph.db -n 1000 -t traverse
|
||||
|
||||
# Pattern matching benchmark
|
||||
ruvector graph benchmark -b ./my-graph.db -n 5000 -t pattern
|
||||
|
||||
# Aggregation benchmark
|
||||
ruvector graph benchmark -b ./my-graph.db -n 2000 -t aggregate
|
||||
```
|
||||
|
||||
**Output:**
|
||||
```
|
||||
Running graph benchmark...
|
||||
Benchmark type: traverse
|
||||
Queries: 1000
|
||||
|
||||
Benchmark Results:
|
||||
Total time: 2.45s
|
||||
Queries per second: 408
|
||||
Average latency: 2.45ms
|
||||
```
|
||||
|
||||
### 8. Start Graph Server
|
||||
|
||||
```bash
|
||||
# Basic server
|
||||
ruvector graph serve -b ./my-graph.db
|
||||
|
||||
# Custom ports
|
||||
ruvector graph serve -b ./my-graph.db --http-port 9000 --grpc-port 50052
|
||||
|
||||
# Public server with GraphQL
|
||||
ruvector graph serve -b ./my-graph.db --host 0.0.0.0 --graphql
|
||||
|
||||
# Full configuration
|
||||
ruvector graph serve \
|
||||
-b ./my-graph.db \
|
||||
--host 0.0.0.0 \
|
||||
--http-port 8080 \
|
||||
--grpc-port 50051 \
|
||||
--graphql
|
||||
```
|
||||
|
||||
**Server Endpoints:**
|
||||
- HTTP: `http://localhost:8080/query`
|
||||
- gRPC: `localhost:50051`
|
||||
- GraphQL: `http://localhost:8080/graphql` (if enabled)
|
||||
|
||||
## Common Workflows
|
||||
|
||||
### Building a Social Network
|
||||
|
||||
```bash
|
||||
# Create database
|
||||
ruvector graph create --path social.db --name social --indexed
|
||||
|
||||
# Start interactive shell
|
||||
ruvector graph shell -b social.db --multiline
|
||||
```
|
||||
|
||||
**In the shell:**
|
||||
```cypher
|
||||
-- Create nodes
|
||||
CREATE (alice:Person {name: 'Alice', age: 30, interests: ['AI', 'Databases']});
|
||||
CREATE (bob:Person {name: 'Bob', age: 25, interests: ['Rust', 'Systems']});
|
||||
CREATE (carol:Person {name: 'Carol', age: 28, interests: ['AI', 'Rust']});
|
||||
|
||||
-- Create relationships
|
||||
MATCH (a:Person {name: 'Alice'}), (b:Person {name: 'Bob'})
|
||||
CREATE (a)-[:KNOWS {since: 2020, strength: 0.8}]->(b);
|
||||
|
||||
MATCH (b:Person {name: 'Bob'}), (c:Person {name: 'Carol'})
|
||||
CREATE (b)-[:KNOWS {since: 2021, strength: 0.9}]->(c);
|
||||
|
||||
-- Query friends
|
||||
MATCH (a:Person {name: 'Alice'})-[:KNOWS]->(friend)
|
||||
RETURN friend.name, friend.age;
|
||||
|
||||
-- Find friends of friends
|
||||
MATCH (a:Person {name: 'Alice'})-[:KNOWS*2..3]-(fof)
|
||||
WHERE fof.name <> 'Alice'
|
||||
RETURN DISTINCT fof.name;
|
||||
|
||||
-- Find common interests
|
||||
MATCH (p:Person)
|
||||
WHERE ANY(interest IN p.interests WHERE interest IN ['AI', 'Rust'])
|
||||
RETURN p.name, p.interests;
|
||||
```
|
||||
|
||||
### Knowledge Graph RAG System
|
||||
|
||||
```bash
|
||||
# Create knowledge graph
|
||||
ruvector graph create --path knowledge.db --name kg --indexed
|
||||
|
||||
# Import from JSON
|
||||
ruvector graph import -b knowledge.db -i documents.json --format json
|
||||
|
||||
# Query for similar concepts
|
||||
ruvector graph query -b knowledge.db -q \
|
||||
"MATCH (d:Document)-[:MENTIONS]->(c:Concept)
|
||||
WHERE c.name = 'Machine Learning'
|
||||
RETURN d.title, d.content"
|
||||
|
||||
# Export for backup
|
||||
ruvector graph export -b knowledge.db -o kg-backup.cypher --format cypher
|
||||
```
|
||||
|
||||
### Recommendation Engine
|
||||
|
||||
```bash
|
||||
# Create recommendations graph
|
||||
ruvector graph create --path recommendations.db --name rec
|
||||
|
||||
# Import user-item interactions
|
||||
ruvector graph import -b recommendations.db -i interactions.csv --format csv
|
||||
|
||||
# Find recommendations via collaborative filtering
|
||||
ruvector graph query -b recommendations.db -q \
|
||||
"MATCH (u:User {id: '123'})-[:LIKED]->(i:Item)<-[:LIKED]-(other:User)
|
||||
MATCH (other)-[:LIKED]->(rec:Item)
|
||||
WHERE NOT (u)-[:LIKED]->(rec)
|
||||
RETURN rec.name, COUNT(*) as score
|
||||
ORDER BY score DESC
|
||||
LIMIT 10"
|
||||
```
|
||||
|
||||
## Advanced Usage
|
||||
|
||||
### Batch Import with Error Handling
|
||||
|
||||
```bash
|
||||
# Skip errors and continue importing
|
||||
ruvector graph import -b ./db.db -i large-dataset.json --skip-errors
|
||||
```
|
||||
|
||||
### Performance Testing
|
||||
|
||||
```bash
|
||||
# Run comprehensive benchmarks
|
||||
for type in traverse pattern aggregate; do
|
||||
echo "Testing $type..."
|
||||
ruvector graph benchmark -b ./db.db -n 10000 -t $type
|
||||
done
|
||||
```
|
||||
|
||||
### Multi-Graph Management
|
||||
|
||||
```bash
|
||||
# Create multiple graphs in same database
|
||||
ruvector graph query -b ./db.db -q "CREATE DATABASE users"
|
||||
ruvector graph query -b ./db.db -q "CREATE DATABASE products"
|
||||
|
||||
# Import to specific graphs
|
||||
ruvector graph import -b ./db.db -i users.json -g users
|
||||
ruvector graph import -b ./db.db -i products.json -g products
|
||||
|
||||
# Query specific graph
|
||||
ruvector graph query -b ./db.db -g users -q "MATCH (n:User) RETURN n"
|
||||
```
|
||||
|
||||
### Server Deployment
|
||||
|
||||
```bash
|
||||
# Development server
|
||||
ruvector graph serve -b ./dev.db --host 127.0.0.1 --http-port 8080
|
||||
|
||||
# Production server with GraphQL
|
||||
ruvector graph serve \
|
||||
-b /data/prod.db \
|
||||
--host 0.0.0.0 \
|
||||
--http-port 8080 \
|
||||
--grpc-port 50051 \
|
||||
--graphql
|
||||
```
|
||||
|
||||
## Global Options
|
||||
|
||||
All graph commands support these global options:
|
||||
|
||||
```bash
|
||||
# Use custom config
|
||||
ruvector --config ./custom-config.toml graph query -q "MATCH (n) RETURN n"
|
||||
|
||||
# Enable debug mode
|
||||
ruvector --debug graph info -b ./db.db
|
||||
|
||||
# Disable colors (for scripting)
|
||||
ruvector --no-color graph query -q "MATCH (n) RETURN n" --format json
|
||||
```
|
||||
|
||||
## Tips and Best Practices
|
||||
|
||||
1. **Use Short Flags for Common Options:**
|
||||
- `-b` for `--db` (database path)
|
||||
- `-q` for `--cypher` (query string)
|
||||
- `-i` for `--input` (import file)
|
||||
- `-o` for `--output` (export file)
|
||||
- `-g` for `--graph` (graph name)
|
||||
- `-n` for `--queries` (benchmark count)
|
||||
- `-t` for `--bench-type` (benchmark type)
|
||||
|
||||
2. **Interactive Mode Best Practices:**
|
||||
- Use `--multiline` for complex queries
|
||||
- End queries with `;` in multiline mode
|
||||
- Use `:clear` to reset query buffer
|
||||
- Use `:help` for shell commands
|
||||
|
||||
3. **Performance:**
|
||||
- Enable `--indexed` for large graphs
|
||||
- Use benchmarks to test query performance
|
||||
- Monitor with `--detailed` info flag
|
||||
|
||||
4. **Data Management:**
|
||||
- Always backup with `export` before major changes
|
||||
- Use `--skip-errors` for large imports
|
||||
- Export to multiple formats for compatibility
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Command Not Found
|
||||
```bash
|
||||
# Ensure binary is built
|
||||
cargo build --package ruvector-cli --bin ruvector
|
||||
|
||||
# Use from target directory
|
||||
./target/debug/ruvector graph --help
|
||||
```
|
||||
|
||||
### Flag Conflicts
|
||||
Remember that global flags take precedence:
|
||||
- Use `-b` for `--db` (NOT `-d`, which is `--debug`)
|
||||
- Use `-q` for `--cypher` (NOT `-c`, which is `--config`)
|
||||
|
||||
### Server Won't Start
|
||||
```bash
|
||||
# Check if port is in use
|
||||
lsof -i :8080
|
||||
|
||||
# Use different port
|
||||
ruvector graph serve -b ./db.db --http-port 9000
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. See [cli-graph-commands.md](../docs/cli-graph-commands.md) for detailed command reference
|
||||
2. Check [neo4j-integration.md](../docs/neo4j-integration.md) for integration details
|
||||
3. Read [configuration.md](../docs/configuration.md) for advanced settings
|
||||
|
||||
## Integration Status
|
||||
|
||||
Current implementation provides CLI interface with placeholder functions. All commands are ready for integration with the `ruvector-neo4j` crate for full Neo4j-compatible graph database functionality.
|
||||
|
||||
**TODO markers in code indicate integration points:**
|
||||
```rust
|
||||
// TODO: Integrate with ruvector-neo4j Neo4jGraph implementation
|
||||
```
|
||||
361
vendor/ruvector/examples/docs/graph_wasm_usage.html
vendored
Normal file
361
vendor/ruvector/examples/docs/graph_wasm_usage.html
vendored
Normal file
@@ -0,0 +1,361 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>RuVector Graph WASM Demo</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background: #f5f5f5;
|
||||
}
|
||||
.container {
|
||||
background: white;
|
||||
border-radius: 8px;
|
||||
padding: 30px;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
||||
}
|
||||
h1 {
|
||||
color: #333;
|
||||
border-bottom: 3px solid #4CAF50;
|
||||
padding-bottom: 10px;
|
||||
}
|
||||
.demo-section {
|
||||
margin: 30px 0;
|
||||
padding: 20px;
|
||||
background: #f9f9f9;
|
||||
border-radius: 6px;
|
||||
border-left: 4px solid #4CAF50;
|
||||
}
|
||||
button {
|
||||
background: #4CAF50;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 12px 24px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
font-size: 14px;
|
||||
margin: 5px;
|
||||
transition: background 0.3s;
|
||||
}
|
||||
button:hover {
|
||||
background: #45a049;
|
||||
}
|
||||
button:disabled {
|
||||
background: #ccc;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
.output {
|
||||
background: #2d2d2d;
|
||||
color: #f8f8f2;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin-top: 15px;
|
||||
font-family: 'Courier New', monospace;
|
||||
font-size: 13px;
|
||||
max-height: 400px;
|
||||
overflow-y: auto;
|
||||
}
|
||||
.stats {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||||
gap: 15px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
.stat-card {
|
||||
background: white;
|
||||
padding: 15px;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #ddd;
|
||||
text-align: center;
|
||||
}
|
||||
.stat-value {
|
||||
font-size: 32px;
|
||||
font-weight: bold;
|
||||
color: #4CAF50;
|
||||
}
|
||||
.stat-label {
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
margin-top: 5px;
|
||||
}
|
||||
.loading {
|
||||
text-align: center;
|
||||
padding: 40px;
|
||||
color: #666;
|
||||
}
|
||||
.error {
|
||||
background: #ffebee;
|
||||
color: #c62828;
|
||||
padding: 15px;
|
||||
border-radius: 4px;
|
||||
margin: 15px 0;
|
||||
border-left: 4px solid #c62828;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>🔗 RuVector Graph WASM Demo</h1>
|
||||
<div id="loading" class="loading">
|
||||
<p>Loading WebAssembly module...</p>
|
||||
</div>
|
||||
<div id="error" style="display: none;" class="error"></div>
|
||||
<div id="content" style="display: none;">
|
||||
<div class="demo-section">
|
||||
<h2>Database Operations</h2>
|
||||
<button onclick="createSampleGraph()">Create Sample Graph</button>
|
||||
<button onclick="createHypergraph()">Create Hypergraph</button>
|
||||
<button onclick="queryGraph()">Query Nodes</button>
|
||||
<button onclick="exportCypher()">Export as Cypher</button>
|
||||
<button onclick="clearDatabase()">Clear Database</button>
|
||||
</div>
|
||||
|
||||
<div class="demo-section">
|
||||
<h2>Statistics</h2>
|
||||
<div class="stats" id="stats">
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="nodeCount">0</div>
|
||||
<div class="stat-label">Nodes</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="edgeCount">0</div>
|
||||
<div class="stat-label">Edges</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="hyperedgeCount">0</div>
|
||||
<div class="stat-label">Hyperedges</div>
|
||||
</div>
|
||||
<div class="stat-card">
|
||||
<div class="stat-value" id="avgDegree">0.0</div>
|
||||
<div class="stat-label">Avg Degree</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="demo-section">
|
||||
<h2>Console Output</h2>
|
||||
<div class="output" id="output">Ready to execute operations...</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script type="module">
|
||||
import init, { GraphDB } from '../npm/packages/graph-wasm/ruvector_graph_wasm.js';
|
||||
|
||||
let db;
|
||||
|
||||
async function initWasm() {
|
||||
try {
|
||||
await init();
|
||||
db = new GraphDB('cosine');
|
||||
document.getElementById('loading').style.display = 'none';
|
||||
document.getElementById('content').style.display = 'block';
|
||||
log('✅ WASM module loaded successfully');
|
||||
log('✅ GraphDB initialized with cosine distance metric');
|
||||
updateStats();
|
||||
} catch (error) {
|
||||
showError('Failed to initialize WASM: ' + error.message);
|
||||
}
|
||||
}
|
||||
|
||||
window.createSampleGraph = function() {
|
||||
try {
|
||||
log('Creating sample social network graph...');
|
||||
|
||||
// Create people
|
||||
const alice = db.createNode(['Person'], {
|
||||
name: 'Alice',
|
||||
age: 30,
|
||||
city: 'New York'
|
||||
});
|
||||
log(`Created node: Alice (${alice})`);
|
||||
|
||||
const bob = db.createNode(['Person'], {
|
||||
name: 'Bob',
|
||||
age: 35,
|
||||
city: 'San Francisco'
|
||||
});
|
||||
log(`Created node: Bob (${bob})`);
|
||||
|
||||
const charlie = db.createNode(['Person'], {
|
||||
name: 'Charlie',
|
||||
age: 28,
|
||||
city: 'New York'
|
||||
});
|
||||
log(`Created node: Charlie (${charlie})`);
|
||||
|
||||
// Create company
|
||||
const company = db.createNode(['Company'], {
|
||||
name: 'TechCorp',
|
||||
founded: 2010
|
||||
});
|
||||
log(`Created node: TechCorp (${company})`);
|
||||
|
||||
// Create relationships
|
||||
const friendship1 = db.createEdge(alice, bob, 'KNOWS', {
|
||||
since: 2015,
|
||||
strength: 0.9
|
||||
});
|
||||
log(`Created edge: Alice KNOWS Bob`);
|
||||
|
||||
const friendship2 = db.createEdge(bob, charlie, 'KNOWS', {
|
||||
since: 2018,
|
||||
strength: 0.7
|
||||
});
|
||||
log(`Created edge: Bob KNOWS Charlie`);
|
||||
|
||||
const works1 = db.createEdge(alice, company, 'WORKS_AT', {
|
||||
since: 2020,
|
||||
position: 'Engineer'
|
||||
});
|
||||
log(`Created edge: Alice WORKS_AT TechCorp`);
|
||||
|
||||
const works2 = db.createEdge(charlie, company, 'WORKS_AT', {
|
||||
since: 2019,
|
||||
position: 'Designer'
|
||||
});
|
||||
log(`Created edge: Charlie WORKS_AT TechCorp`);
|
||||
|
||||
log('✅ Sample graph created successfully!');
|
||||
updateStats();
|
||||
} catch (error) {
|
||||
showError('Error creating graph: ' + error.message);
|
||||
}
|
||||
};
|
||||
|
||||
window.createHypergraph = function() {
|
||||
try {
|
||||
log('Creating hypergraph example...');
|
||||
|
||||
// Create documents with embeddings
|
||||
const doc1 = db.createNode(['Document'], {
|
||||
title: 'AI Research Paper',
|
||||
embedding: generateRandomEmbedding(384)
|
||||
});
|
||||
log(`Created document node: ${doc1}`);
|
||||
|
||||
const doc2 = db.createNode(['Document'], {
|
||||
title: 'ML Tutorial',
|
||||
embedding: generateRandomEmbedding(384)
|
||||
});
|
||||
log(`Created document node: ${doc2}`);
|
||||
|
||||
const author = db.createNode(['Person'], {
|
||||
name: 'Dr. Smith',
|
||||
embedding: generateRandomEmbedding(384)
|
||||
});
|
||||
log(`Created author node: ${author}`);
|
||||
|
||||
// Create hyperedge connecting all three
|
||||
const hyperedge = db.createHyperedge(
|
||||
[doc1, doc2, author],
|
||||
'Research papers authored by Dr. Smith on related AI topics',
|
||||
null, // Auto-generate embedding
|
||||
0.95
|
||||
);
|
||||
log(`Created hyperedge: ${hyperedge}`);
|
||||
|
||||
const he = db.getHyperedge(hyperedge);
|
||||
log(`Hyperedge order (connected nodes): ${he.order}`);
|
||||
log(`Hyperedge confidence: ${he.confidence}`);
|
||||
|
||||
log('✅ Hypergraph created successfully!');
|
||||
updateStats();
|
||||
} catch (error) {
|
||||
showError('Error creating hypergraph: ' + error.message);
|
||||
}
|
||||
};
|
||||
|
||||
window.queryGraph = async function() {
|
||||
try {
|
||||
log('Querying graph for Person nodes...');
|
||||
|
||||
// Note: Full Cypher support is limited in this version
|
||||
// This demonstrates the API even if query parsing is basic
|
||||
const results = await db.query('MATCH (n:Person) RETURN n');
|
||||
|
||||
log(`Query returned ${results.count} results`);
|
||||
log(`Nodes: ${results.nodes.length}`);
|
||||
log(`Edges: ${results.edges.length}`);
|
||||
log(`Hyperedges: ${results.hyperedges.length}`);
|
||||
|
||||
if (results.isEmpty()) {
|
||||
log('No results found. Try creating a sample graph first.');
|
||||
} else {
|
||||
log('✅ Query executed successfully!');
|
||||
}
|
||||
|
||||
updateStats();
|
||||
} catch (error) {
|
||||
showError('Error querying graph: ' + error.message);
|
||||
}
|
||||
};
|
||||
|
||||
window.exportCypher = function() {
|
||||
try {
|
||||
log('Exporting database as Cypher...');
|
||||
const cypher = db.exportCypher();
|
||||
|
||||
if (cypher.trim() === '') {
|
||||
log('Database is empty. Nothing to export.');
|
||||
} else {
|
||||
log('Exported Cypher statements:');
|
||||
log('');
|
||||
log(cypher);
|
||||
log('✅ Export complete!');
|
||||
}
|
||||
} catch (error) {
|
||||
showError('Error exporting: ' + error.message);
|
||||
}
|
||||
};
|
||||
|
||||
window.clearDatabase = function() {
|
||||
try {
|
||||
log('Clearing database...');
|
||||
db = new GraphDB('cosine');
|
||||
log('✅ Database cleared!');
|
||||
updateStats();
|
||||
} catch (error) {
|
||||
showError('Error clearing database: ' + error.message);
|
||||
}
|
||||
};
|
||||
|
||||
function updateStats() {
|
||||
try {
|
||||
const stats = db.stats();
|
||||
document.getElementById('nodeCount').textContent = stats.nodeCount;
|
||||
document.getElementById('edgeCount').textContent = stats.edgeCount;
|
||||
document.getElementById('hyperedgeCount').textContent = stats.hyperedgeCount;
|
||||
document.getElementById('avgDegree').textContent = stats.avgEntityDegree.toFixed(2);
|
||||
} catch (error) {
|
||||
console.error('Error updating stats:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function log(message) {
|
||||
const output = document.getElementById('output');
|
||||
const timestamp = new Date().toLocaleTimeString();
|
||||
output.innerHTML += `[${timestamp}] ${message}\n`;
|
||||
output.scrollTop = output.scrollHeight;
|
||||
}
|
||||
|
||||
function showError(message) {
|
||||
const errorDiv = document.getElementById('error');
|
||||
errorDiv.textContent = message;
|
||||
errorDiv.style.display = 'block';
|
||||
log('❌ ERROR: ' + message);
|
||||
}
|
||||
|
||||
function generateRandomEmbedding(dim) {
|
||||
return Array.from({ length: dim }, () => Math.random() * 2 - 1);
|
||||
}
|
||||
|
||||
// Initialize on page load
|
||||
initWasm();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user