Skip to content

franrob-projects/bjj-move-graph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BJJ Move Graph

A Neo4j graph database mapping Brazilian Jiu-Jitsu techniques, positions, and the relationships between them — with a live interactive visualisation and a REST API.

Neo4j Node.js TypeScript Docker


Why a graph database?

BJJ is inherently a graph problem. Positions connect to techniques, techniques chain into other techniques, some techniques counter others, and everything feeds back into positions. A relational database forces you to flatten that into join tables. Neo4j lets the data keep its natural shape — and opens up queries that would be painful or impossible in SQL, like shortest path between two positions or finding the most "central" technique in the entire game.

(Position)-[:AVAILABLE_FROM]-->(Technique)
(Technique)-[:TRANSITIONS_TO]-->(Position)
(Technique)-[:CHAINS_INTO]---->(Technique)
(Technique)-[:COUNTERS]------->(Technique)

What's in the database

13 positions — Standing, Closed Guard, Open Guard, Half Guard, Butterfly Guard, De La Riva, Ashi Garami, Mount, Back Control, Side Control, Knee on Belly, North-South, Turtle.

43 techniques across six categories:

Category Count Examples
Submissions 15 Rear Naked Choke, Triangle, Armbar, Heel Hook
Sweeps 6 Butterfly Sweep, Scissor Sweep, Berimbolo
Passes 6 Knee Slice, Torreando, Double Under
Escapes 4 Elbow-Knee Escape, Bridge & Roll
Takedowns 5 Double Leg, Single Leg, Guard Pull
Transitions 1 Berimbolo

200+ relationships with weighted frequency data drawn from IBJJF, ADCC, and sub-only event statistics:

Relationship Meaning Weight
AVAILABLE_FROM Technique is accessible from this position Setup frequency (1–100)
TRANSITIONS_TO Technique lands you in this position Transition frequency (1–100)
CHAINS_INTO Technique naturally flows into another Combination frequency + notes
COUNTERS Technique specifically defeats another Counter frequency (1–100)

Graph model

(:Position {
  id, name, description,
  difficulty: 'beginner' | 'intermediate' | 'advanced',
  dominant: 'top' | 'bottom' | 'neutral'
})

(:Technique {
  id, name, description, type,
  difficulty, gi_only,
  competition_frequency  // 1–100
})

Every technique has a competition_frequency score — a normalised value reflecting how often it appears as a finish or meaningful attempt in high-level competition. The Rear Naked Choke scores 92. The Baseball Bat Choke scores 20. Node sizes in the visualisation are proportional to this value.


Getting started

Prerequisites

  • Docker + Docker Compose
  • Node.js 18+

1. Start Neo4j

docker-compose up -d

Neo4j will be available at http://localhost:7474 (login: neo4j / bjjgraph123).

2. Install dependencies

npm install

3. Configure environment

cp .env.example .env

The defaults work out of the box with the Docker Compose setup.

4. Seed the database

npm run seed

This clears any existing data, creates constraints, and inserts all positions, techniques, and relationships. Output looks like:

🥋 BJJ Move Graph — Database Seeder

🗑️  Clearing existing data...
📐 Creating constraints and indexes...
🥋 Seeding 13 positions...
⚡ Seeding 43 techniques...
🔗 Seeding 62 AVAILABLE_FROM relationships...
🔗 Seeding 31 TRANSITIONS_TO relationships...
🔗 Seeding 24 CHAINS_INTO relationships...
🔗 Seeding 12 COUNTERS relationships...

📊 Database summary:
   AVAILABLE_FROM         62
   TRANSITIONS_TO         31
   CHAINS_INTO            24
   Technique              43
   COUNTERS               12
   Position               13

✅ Seed complete. Open http://localhost:7474 to explore.

5. Start the API and visualisation

npm run dev

Open http://localhost:3000 for the interactive graph. The Neo4j browser is at http://localhost:7474 if you want to run raw Cypher queries.


Visualisation

The frontend renders the full graph using Vis.js Network. Nodes are sized by competition frequency and colour-coded by type:

  • 🔷 Blue diamonds — Positions
  • 🔴 Red — Submissions
  • 🟢 Green — Sweeps
  • 🟡 Amber — Passes
  • 🟣 Purple — Escapes
  • 🩵 Cyan — Takedowns
  • 🩷 Pink — Transitions

Click any node to see its description, setup frequency, chains, and counters in the sidebar. Use the filter bar to isolate technique types. The Stats tab shows submission chain rankings and the most-connected techniques in the graph.


API reference

Base URL: http://localhost:3000

Positions

Method Endpoint Description
GET /positions All positions
GET /positions/:id Single position with technique count
GET /positions/:id/techniques Techniques available from this position
GET /positions/:id/danger Submission threats from this position
GET /positions/:id/paths-to-submission Routes to a finish from this position

Techniques

Method Endpoint Description
GET /techniques All techniques (optional ?type=submission)
GET /techniques/most-frequent Top techniques by competition frequency
GET /techniques/most-connected Hub techniques by total graph connections
GET /techniques/:id Full detail — chains, counters, positions

Analysis

Method Endpoint Description
GET /analysis/graph Full node + edge graph for visualisation
GET /analysis/path?from=X&to=Y Shortest path between two positions
GET /analysis/submission-chains Top technique combination sequences
GET /analysis/sector-stats Breakdown by technique type
GET /analysis/position-connectivity Positions ranked by technique availability

Example responses

GET /positions/closed-guard/danger

[
  { "name": "Triangle Choke", "frequency": 78, "setup_frequency": 75, "difficulty": "intermediate" },
  { "name": "Armbar",         "frequency": 85, "setup_frequency": 70, "difficulty": "beginner" },
  { "name": "Kimura",         "frequency": 65, "setup_frequency": 60, "difficulty": "beginner" }
]

GET /analysis/path?from=closed-guard&to=back-control

{
  "from": "closed-guard",
  "to": "back-control",
  "path_length": 3,
  "node_names": ["Closed Guard", "Kimura", "Back Control"],
  "rel_types": ["AVAILABLE_FROM", "TRANSITIONS_TO"]
}

Cypher examples

The cypher/examples.cypher file has 12 ready-to-run queries for the Neo4j browser. A few highlights:

-- Shortest path from closed guard to back control
MATCH (start:Position {id: 'closed-guard'}),
      (end:Position   {id: 'back-control'})
MATCH path = shortestPath((start)-[*..8]-(end))
RETURN [node IN nodes(path) | coalesce(node.name, '')] AS path, length(path) AS steps;

-- Most connected techniques (hub moves)
MATCH (t:Technique)
OPTIONAL MATCH (t)-[out]->()
OPTIONAL MATCH ()-[in]->(t)
WITH t, count(DISTINCT out) AS outDegree, count(DISTINCT in) AS inDegree
RETURN t.name, inDegree + outDegree AS total_connections
ORDER BY total_connections DESC LIMIT 10;

-- Top submission chains
MATCH (a:Technique {type: 'submission'})-[r:CHAINS_INTO]->(b:Technique {type: 'submission'})
RETURN a.name, b.name, r.frequency, r.notes
ORDER BY r.frequency DESC;

Project structure

bjj-move-graph/
├── docker-compose.yml         # Neo4j 5.15 instance
├── src/
│   ├── db/
│   │   └── driver.ts          # Neo4j driver singleton
│   ├── seed/
│   │   ├── data/
│   │   │   ├── positions.ts   # 13 position definitions
│   │   │   ├── techniques.ts  # 43 technique definitions
│   │   │   └── relationships.ts # All weighted relationships
│   │   └── seed.ts            # Seeder runner
│   ├── queries/
│   │   ├── byPosition.ts      # Position-based queries
│   │   ├── mostFrequent.ts    # Frequency and hub analysis
│   │   └── shortestPath.ts    # Path-finding queries
│   └── api/
│       ├── server.ts          # Express app
│       └── routes/
│           ├── positions.ts
│           ├── techniques.ts
│           └── analysis.ts
├── cypher/
│   └── examples.cypher        # 12 example queries for Neo4j browser
└── public/
    └── index.html             # Vis.js interactive visualisation

Frequency data notes

Competition frequency values are normalised estimates based on aggregated finish data from IBJJF gi competition, ADCC, and major sub-only promotions. They reflect general prevalence across skill levels — not elite-only or white-belt-only populations. Gi-only techniques (Bow and Arrow Choke, Baseball Bat Choke, etc.) reflect gi competition frequency only.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors