视觉画布设计
canvas-design
基于设计原则创作静态视觉作品,用于海报与品牌图形。
data-graph-database【文档与办公】Use this skill when asked about Neo4j, Amazon Neptune, JanusGraph, graph database, graph model, Cypher, Gremlin, RDF, SPARQL, graph traversal, property graph, or knowledge graph. This skill enforces: graph data modeling (property graph, RDF), Neo4j/Cypher query patterns, Amazon Neptune/Gremlin traversal, JanusGraph architecture with backend storage, …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Design graph data models for connected domains (social networks, recommendation engines, knowledge graphs, fraud detection) with optimal traversal patterns, platform selection, and scaling strategy.
Exact user phrases: "Neo4j", "Amazon Neptune", "JanusGraph", "graph database", "graph model", "Cypher", "Gremlin", "RDF", "SPARQL", "graph traversal", "property graph", "knowledge graph", "graph schema", "node label", "relationship", "graph query".
Before activating, verify:
Graph data model with node labels, relationship types, traversal patterns, and platform-specific deployment config.
// Neo4j schema + constraints + traversal queries
// Gremlin traversals for Neptune/JanusGraph
# JanusGraph storage backend config
# Neptune cluster config
No preamble. No postamble. No explanations. No filler/hedging/transitions. Compress output — why use many token when few do trick.
300 lines of schema and queries.
Property graph: nodes (entities) with labels, relationships (edges) with types, properties on both. RDF: subject-predicate-object triples with URIs. Design around traversal patterns: ask "what queries will traverse from this node through which relationships?" Favor nodes for entities, relationships for connections, properties for attributes.
// Property graph model for e-commerce
// (:Customer)-[:PURCHASED]->(:Order)-[:CONTAINS]->(:Product)
// (:Customer)-[:REVIEWED]->(:Product)
// Each relationship carries context: timestamp, quantity, rating
Node labels represent entity types. Labels can be hierarchical. Relationship types are directional verbs in present tense. Properties on relationships for context. Avoid generic relationships like RELATED_TO.
// Node labels
CREATE CONSTRAINT customer_id FOR (c:Customer) REQUIRE c.id IS UNIQUE;
CREATE CONSTRAINT product_sku FOR (p:Product) REQUIRE p.sku IS UNIQUE;
// Composite index for lookup
CREATE INDEX customer_region_idx FOR (c:Customer) ON (c.region, c.tier);
Neo4j: BTREE indexes for exact lookups, TEXT for string contains, RANGE for numeric/date, POINT for spatial, FULLTEXT for cross-label search. Composite indexes for multi-property lookups.
// RANGE index for date filtering
CREATE RANGE INDEX order_date_idx FOR ()-[r:PURCHASED]-() ON (r.created_at);
// TEXT index for product search
CREATE TEXT INDEX product_name_idx FOR (p:Product) ON (p.name);
// FULLTEXT for cross-label search
CREATE FULLTEXT INDEX entity_search FOR (n:Customer|Product|Order) ON EACH [n.name, n.description];
Start with most selective pattern. Use LIMIT early. Profile queries to find Expand(Into) vs Expand(All). Avoid cartesian products. Use USING INDEX to force index selection. Parameterize all queries.
// Bad: full scan then filter
MATCH (c:Customer)-[:PURCHASED]->(o:Order)-[:CONTAINS]->(p:Product)
WHERE c.region = 'US' AND p.category = 'Electronics'
RETURN c.name, p.name LIMIT 100;
// Good: start with most selective, use indexes
MATCH (c:Customer) WHERE c.region = 'US'
WITH c LIMIT 100
MATCH (c)-[:PURCHASED]->(o:Order)-[:CONTAINS]->(p:Product)
WHERE p.category = 'Electronics'
RETURN c.name, p.name;
// Profile to verify plan
PROFILE
MATCH (c:Customer) WHERE c.region = 'US'
USING INDEX c:Customer(region)
RETURN count(c);
Neo4j: full ACID, Cypher, strongest ecosystem. Neptune: managed AWS, Gremlin + SPARQL. JanusGraph: open-source, pluggable backend, horizontal scaling.
# JanusGraph with Cassandra + Elasticsearch
storage:
backend: cassandra
hostname: ["10.0.1.10", "10.0.1.11", "10.0.1.12"]
port: 9160
keyspace: janusgraph
index:
search:
backend: elasticsearch
hostname: ["10.0.2.10", "10.0.2.11"]
port: 9200
cache:
db-cache: true
db-cache-clean-wait: 20
Neo4j: causal clustering, read replicas. Neptune: auto-scaling storage. JanusGraph: partition across storage backend, Elasticsearch for indexing.
Neo4j causal clustering: core servers handle writes (RAFT consensus), read replicas handle reads. Minimum 3 core servers for production. Read replicas auto-scale based on query load.
Neptune: serverless or provisioned. Storage auto-scales to 128TB. Use Neptune Streams for change data capture. Enable DFE (Data Format Efficiency) for faster query execution.
JanusGraph: partition graph across Cassandra nodes. Configure ids.block-size based on write rate. Use storage.lock.wait-time for transaction conflict handling.
Neo4j GDS: centrality (PageRank, Betweenness), community detection (Louvain, Label Propagation), path finding (Shortest Path), node similarity (Jaccard, Cosine). Run on projected in-memory graphs.
// Project graph into memory
CALL gds.graph.project('myGraph', 'Customer', {
PURCHASED: { orientation: 'UNDIRECTED' }
});
// Run PageRank
CALL gds.pageRank.stream('myGraph')
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS customer, score
ORDER BY score DESC LIMIT 20;
// Community detection
CALL gds.louvain.stream('myGraph')
YIELD nodeId, communityId
RETURN communityId, count(*) AS members;
// Clean up
CALL gds.graph.drop('myGraph');
Batch: neo4j-admin import, LOAD CSV, APOC. Stream: Kafka connect. Import best practices: temporary nodes for dedup, batch commits every 1000-5000 rows, create constraints before import.
# neo4j-admin bulk import
neo4j-admin database import full \
--nodes=Customer=customers-header.csv,customers.csv \
--nodes=Product=products-header.csv,products.csv \
--relationships=PURCHASED=purchases-header.csv,purchases.csv \
--trim-strings=true \
--ignore-extra-columns=true
// APOC periodic batch commit
CALL apoc.periodic.commit(
"MATCH (c:Customer) WHERE c.batch_id IS NULL
WITH c LIMIT 5000
SET c.batch_id = $batch
RETURN count(*)",
{batch: 123}
);
Ontology with RDF/OWL for formal semantics. Property graph for application use. SKOS for taxonomies. Named entity resolution via sameAs links. Graph embeddings for ML feature extraction.
# RDF ontology snippet
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
@prefix schema: <http://schema.org/> .
@prefix ex: <http://example.org/ontology/> .
ex:Product a rdfs:Class ;
rdfs:label "Product" ;
rdfs:subClassOf schema:Product .
ex:suppliedBy a rdf:Property ;
rdfs:domain ex:Product ;
rdfs:range ex:Supplier .
Graph databases pair naturally with GraphQL APIs. Use Neo4j GraphQL library to auto-generate GraphQL schema from the graph model. This provides real-time graph traversal through a standard API.
// Neo4j GraphQL schema
const typeDefs = `
type Customer {
id: ID!
name: String!
email: String!
purchased: [Order!]! @relationship(type: "PURCHASED", direction: OUT)
}
type Order {
id: ID!
total: Float!
createdAt: DateTime!
contains: [Product!]! @relationship(type: "CONTAINS", direction: OUT)
customer: Customer! @relationship(type: "PURCHASED", direction: IN)
}
type Product {
id: ID!
name: String!
sku: String!
category: String!
reviews: [Review!]! @relationship(type: "REVIEWED", direction: IN)
}
`;
Need graph database?
├── Full ACID, rich ecosystem, Cypher? → Neo4j
├── AWS-managed, Gremlin + SPARQL? → Neptune
├── Open source, horizontal scale, pluggable? → JanusGraph
├── Large-scale analytics, not OLTP? → TigerGraph
├── RDF/SPARQL knowledge graph? → Stardog / GraphDB
└── Graph visualization and exploration? → Neo4j + Bloom / Linkurious
Design traversal:
1. List all query patterns
2. Identify entities → nodes
3. Identify connections → relationships
4. Identify attributes → properties
5. Choose property location (node vs relationship)
6. Define indexes for entry-point lookups
7. Profile traversal with representative data
Property placement decision:
Attribute that describes the connection? → relationship property
Attribute that belongs to the entity? → node property
Attribute varies per connection? → relationship property
Attribute is constant for entity? → node property
RELATED_TO, CONNECTED_TO lose semantic meaning. Use specific verbs: PURCHASED, MANAGED_BY, LOCATED_IN.| Feature | Neo4j | Neptune | JanusGraph | TigerGraph |
|---|---|---|---|---|
| ACID | Yes | Per-transaction | Per-backend | Yes |
| Query | Cypher | Gremlin + SPARQL | Gremlin | GSQL |
| Scaling | Read replicas, causal clustering | Multi-AZ, storage auto-scale | Horizontal (Cassandra) | MPP shared-nothing |
| Storage | Native graph | Internal | Pluggable | Native MPP |
| HA | Causal clustering | Built-in | Backend-dependent | Built-in |
| Cloud | Aura | AWS | Any | TigerGraph Cloud |
| In-memory analytics | GDS | DFE | N/A | Built-in |
| OLTP vs OLAP | Both | Both | OLTP-heavy | OLAP-heavy |
| Ecosystem | Largest | AWS-native | Open-source | Growing |
Graph vs relational: graph excels at many-to-many relationships, variable-depth traversals, and path queries. Relational excels at aggregate queries, strict schemas, and ACID-compliant transactions over known relationships. Use graph when the value is in the connections, not just the entities.
Graph vs document (MongoDB): document stores embed related data, limiting traversal to one level. Graph stores normalize relationships, enabling arbitrary-depth traversal. Use graph for highly connected data, document for aggregate-root patterns.
| Tool | Purpose |
|---|---|
| Neo4j Browser | Query editor and visualization |
| Neo4j GDS | Graph algorithms library |
| APOC | Utility procedures |
| Cypher Shell | Command-line query tool |
| Gremlin Console | Server-less query testing |
| Neptune Workbench | Jupyter notebooks for Neptune |
| JanusGraph Server | Gremlin server with backend config |
| Arrows | Graph data modeling visualization |
| Neo4j Bloom | Graph visualization for business users |
| Linkurious | Graph visualization and investigation |
| GraphXR | 3D graph visualization |
| Apache TinkerPop | Graph computing framework |
| Neo4j GraphQL | Auto-generated GraphQL from graph model |
| RDF4J / Jena | RDF and SPARQL toolkits |
| Stardog | Enterprise RDF knowledge graph |
Graph Database Selection
├── Query pattern?
│ ├── OLTP (transactions) → Neo4j (property graph, ACID)
│ ├── OLAP (analytics) → JanusGraph + Spark / TigerGraph
│ └── RDF/Semantic web → Amazon Neptune / Stardog
├── Scale requirements?
│ ├── < 10B edges → Neo4j (single instance or causal cluster)
│ ├── 10B-100B edges → JanusGraph (distributed, HBase/Cassandra backend)
│ └── > 100B edges → TigerGraph (native parallel graph)
├── Real-time traversal?
│ ├── Yes → Neo4j / TigerGraph (native graph store)
│ └── No → JanusGraph / Neptune
└── Cloud-managed?
├── Yes → Neptune / Neo4j Aura
└── No → Self-managed Neo4j / JanusGraph on K8s
Decision criteria: Evaluate query latency, graph size, team Cypher/Gremlin/SPARQL expertise, and operational overhead tolerance.
// graph_database/fraud_patterns.cypher
MATCH (u:User)-[:MADE_TRANSFER]->(t:Transaction)-[:TO_ACCOUNT]->(a:Account)
WHERE t.amount > 10000
AND t.timestamp > datetime() - duration('PT1H')
WITH u, a, count(t) as tx_count, sum(t.amount) as total_amount
WHERE tx_count > 3
OPTIONAL MATCH (a)<-[:TO_ACCOUNT]-(:Transaction)<-[:MADE_TRANSFER]-(other:User)
WHERE other <> u
RETURN u.id, a.id, tx_count, total_amount, count(DISTINCT other) as connected_users
ORDER BY total_amount DESC
# graph_database/node2vec_embedding.py
from node2vec import Node2Vec
import networkx as nx
class GraphEmbedding:
def __init__(self, graph: nx.Graph):
self.graph = graph
def generate_embeddings(self, dimensions: int = 128, walk_length: int = 80):
n2v = Node2Vec(
self.graph,
dimensions=dimensions,
walk_length=walk_length,
num_walks=10,
workers=4
)
model = n2v.fit(window=10, min_count=1)
embeddings = {node: model.wv[node].tolist() for node in self.graph.nodes()}
return embeddings
PROFILE; monitor full-node scans vs index lookups.| Anti-Pattern | Consequence | Solution |
|---|---|---|
| No indexes on query properties | Full store scan on every query | Create indexes on filtered properties |
| Deep traversals without LIMIT | Query timeout, server OOM | Always use LIMIT + pagination |
| Storing large blob properties in graph | Graph bloat, slow traversals | Store blobs in S3; reference by URL |
| Using Cypher for ETL | Slow, not designed for bulk | Use neo4j-admin import or Spark connector |
| Ignoring relationship direction | Wrong query results, confusion | Explicitly define and document direction |
apoc.periodic.iterate for large batch operations instead of single large queries.neo4j/neo4j credentials.data-nosql-database for non-relational data stores
ml-feature-engineering for graph feature extraction (PageRank, embeddings)