Searching by Meaning
Word search finds a column when the question uses its name. Search by meaning also finds it when the name says nothing: a column called net_sales_amt answers “revenue”, because its name expands (amt is amount, sales are revenue), its formula reads columns named for revenue, and the columns upstream of it and the business terms that define it say the same.
konstruct search --meaning revenue -n 3
orders.revenue table DOUBLE
stg_orders.rev table sql/staging.sql
fct_sales.net_sales_amt table by lineage sql/marts.sql
Here raw.orders.revenue is renamed rev in staging, and the mart computes rev - refund_amt_gbp as net_sales_amt: word search finds the first two, and only search by meaning the third.
The same search is project.search('revenue', mode='semantic') in the Python API and the MCP tool search with mode='semantic'. Each result has a score and, in --json and to_dict(), matched: what a match by meaning rests on most.
|
The match comes from |
|---|---|
|
The node’s own name, synonyms or description, read with the abbreviations and synonyms of data work: |
|
What its neighbours are called: the columns upstream and downstream of it, its table, and above all the business terms bound to it |
|
Its formula, composed through the columns upstream: the functions, operators and constants it uses and the columns it reads. A column that only copies or renames another computes nothing, so it never matches by formula |
|
Its place in the lineage: built from the same sources by the same path (in |
A node is found only through a word, concept or formula token it shares with the question, never through shared letters alone, and words the project never uses are left out of the question: a search for something the project does not hold finds nothing.
Every kind of node can be found: columns, models, tables, sources, tasks, tests, dashboards and business terms. --kind column (kinds=['column']) keeps only some kinds.
Exact Names First
Search by meaning is fused with word search, so it never loses what word search finds: a node named exactly what was asked for comes first, and a node both searches rank highly comes before one only one of them finds. A question that reads as a formula, such as price * quantity or coalesce(discount, 0), is answered by its formula: the columns that compute it, not the columns it names.
Similar Columns
semantic.similar(graph, 'fct_sales.line_total') lists the nodes most like one node: named alike, near it in the lineage, computed by the same formula, or built from the same sources by the same path. similar is a way to find the other copies of a measure.
The Index
The first search by meaning makes the index and saves it as konstruct-out/vectors.bin beside graph.json, so a build spends nothing on it. The file holds the index and every node’s blocks, with a digest of the graph they were computed from: a later search on the same graph, in any process, reads them rather than computing them. After a build changes the graph, the first search computes the blocks again, reinserts only the nodes whose meaning changed (a renamed column, and the columns around it), and saves the file again; a file from another version of Konstruct is replaced. When the output directory cannot be written to, the index is made in memory each time.
Everything is computed locally from the graph: no model is downloaded, no service is called and nothing leaves the machine. The same graph gives the same results on every machine.