Find records that connect groups
The language tabs use earlier client interfaces. Check SDK versions and connection setup before running them.
Betweenness measures how often a node lies on shortest paths between other nodes. High values can reveal bridges in a network.
Before you run it: If the work budget is exceeded, use the suggested sample count or reduce the graph rather than retrying the same exact request.
First load the five-person social graph. It creates the exact social.users table and follows relation used below.
A bridge connects parts of a network that would otherwise need a longer route. The score is a structural clue, not proof that the person or account is suspicious.
- Load the linked recordsChoose the self-relation to analyze.
- Inspect shortest routesUse the configured exact or sampled analysis.
- Score the connecting nodesCount how often records bridge those routes.
- Check the analysis metadataRead estimated and pivot details before interpreting scores.
Follow the example
- Prepare a self-referencing relationship.
- Choose exact calculation or explicit sampling.
- Run within node and work limits.
- Inspect high-scoring nodes and their links.
Set up the relationship
The relation must be declared in the schema's [[relations]] block and must target the table it is declared on. See schemas/reference#relations.
Run the request
rel is required. max_nodes defaults to the 100,000-node ceiling. Exact calculation is the default; samples=K explicitly chooses an estimate using K pivot nodes. seed controls which pivots are selected.
curl -G "https://$OC_HOST/v1/tenants/$OC_TENANT/graph/social.users/betweenness" \
--data-urlencode "rel=follows" \
-H "Authorization: Bearer $OC_TOKEN"Check the result
Sampled results include estimated status and pivot information alongside scores.
[
{ "pk": ["dave"], "betweenness": 8.0 },
{ "pk": ["carol"], "betweenness": 5.0 },
{ "pk": ["bob"], "betweenness": 1.0 },
{ "pk": ["alice"], "betweenness": 0.0 },
{ "pk": ["mallory"], "betweenness": 0.0 }
][
{ "pk": ["dave"], "betweenness": 7.6, "estimated": true, "pivots": 500 },
{ "pk": ["carol"], "betweenness": 4.8, "estimated": true, "pivots": 500 }
]One row per node, sorted by score descending, with pk as the primary-key array. In exact mode - the first body above - each row has exactly two fields: there is no estimated and no pivots key at all, so a parser written against the exact shape keeps working. Add samples=K and you get the second body: every row is tagged estimated: true with the pivot count, which is what lets a consumer holding only the response tell that it is looking at an approximation.
Understand the behavior
- Brandes' algorithm runs a single-source shortest-path pass from every node and accumulates dependency scores on the way back.
- Cost grows with nodes times edges, so this endpoint refuses on predicted work, not on node count. The refusal is a tagged
graph_work_budget_exceeded400 that quotes the node and edge counts, the predicted seconds, and thesamples=value that would fit - it tells you what to do instead of timing out. - Sampled mode runs the same pass from K randomly chosen pivots instead of from every node, which is what makes a large graph fit inside a request.
seedfixes pivot selection and has a fixed default, so a sampled result is reproducible even when you do not pass one.- Sampling only helps where the graph has a distinguishable head. Take the ratio of the top score to the median over the rows you get back: where that ratio is large the sampled ranking tracks the exact one closely, and where it is close to one every node has nearly the same betweenness and no ranking of that graph means much - including the exact one.
Important limits and checks
- Assuming a hub scores highly. Degree and betweenness answer different questions. A node with many neighbours who all know each other is a poor bridge and scores near zero.
- Retrying a work-budget 400. It is not a transient failure. The engine is telling you the exact call is too big and naming the
samples=value that fits - change the request, do not repeat it. - Comparing a sampled score against an exact one. Estimated scores are only approximately on the same scale. Compare rankings rather than values, and check the
estimatedflag before you do either. - Passing
max_nodes=0orsamples=0. Both are refused with a 400. An empty universe and a zero-pivot estimate are not meaningful requests.