Klarety

Knowledge graph

Define, build and walk the graph of the things in your data and how they connect.

For devs

The shows the things in your data (customers, orders, sites) and how they connect. Nothing is copied: a node type is a with a key, and an edge type says how two node types connect.

Use it to walk around a record, find the shortest path between two records, or find records that are the same real thing.

In the app, browse the graph in Data, under Knowledge graph.

Before you start

  • The tables you want in the graph exist and have a key column.
  • Every example assumes nexus = Nexus.connect().

See what is there

overview = nexus.knowledge_graph.overview()   # node types with row counts, and edge types
print(overview)
print(nexus.knowledge_graph.status())          # when each edge type was last built

Change the definition

The definition names existing tables and columns, and is checked before it is kept.

Read, edit and save

from klarety import ConflictError, RefusedError

current = nexus.knowledge_graph.definition()
definition = current["definition"]
# change the node and edge types here

try:
    nexus.knowledge_graph.define(definition, version=current["version"])
except (ConflictError, RefusedError) as refused:
    print("Not saved. Read the graph again if it changed:", refused)

define() replaces your part of the definition whole, and is refused if the graph changed since you read version.

Check it against your data

for result in nexus.knowledge_graph.check("customer", "order"):
    print(result)

check() takes 1 to 16 type names and reports keys that are missing or repeated and edges that point nowhere.

Build inferred edges

nexus.knowledge_graph.build()                   # every edge type you may build
nexus.knowledge_graph.build("same_customer", rebuild=True)

Building runs in the background; watch status() to see when it finishes.

To add edges you already know, send up to 1,000 at a time; each is kept only where both rows exist:

queued = nexus.knowledge_graph.assert_edges("supplies", edges)

Walk the graph

Start from a record

keys = nexus.knowledge_graph.nodes("customer", starts_with="ACME")
around = nexus.knowledge_graph.around("customer", keys[0], hops=2)
for node in around["nodes"]:
    print(node)

around() returns nodes within hops (at most 3), nearest first. Pass next_cursor back as cursor for the next page. stopped_at_budget means the walk hit your plan's budget first.

Find a path

paths = nexus.knowledge_graph.path(("customer", "C-1"), ("supplier", "S-9"), hops=4)

path() returns the shortest ways one record reaches another, step by step, within hops (at most 4). It is empty when there is none.

Same, similar and central

nexus.knowledge_graph.same_as("customer", "C-1")                  # the same real thing
nexus.knowledge_graph.similar("product", "embedding", vector)     # nearest by a vector column
nexus.knowledge_graph.communities()                               # groups
nexus.knowledge_graph.central(node_type="customer")               # most connected

Search everything at once

nexus.search() ranks files by their names and tags, rows nearest a vector, and what those rows connect to, in one list:

for hit in nexus.search("solar panel invoice", limit=10):
    print(hit)

What can go wrong

ExceptionCauseWhat to do
ConflictError or RefusedError on define()The definition changed since you read it, or it names something that does not exist.Read it again and reapply your change, or fix the names.
RefusedErrorThe definition names a table or column that does not exist, or you cannot reach it.Fix the names.
ValueErrorcheck() was called with no names.Name 1 to 16 types.

Next steps

On this page