Documentation
¶
Index ¶
- Constants
- Variables
- func AsOf(ctx context.Context, at time.Time) context.Context
- func DerivedEdgeID(ruleID, fromNodeID, toNodeID, edgeType string) string
- func IsRuleVariable(term string) bool
- func NotInTypes(column string, types []string) string
- func WithReadOptions(ctx context.Context, opts ReadOptions) context.Context
- type AllenRelation
- type Atom
- type BatchEdgeOperation
- type BatchGraphOperation
- type BatchNodeOperation
- type BatchResult
- type Community
- type Connectivity
- type DiffKind
- type DiffOptions
- type EdgeChange
- type EdgeEndpoint
- type EdgeEndpointPair
- type EdgePrediction
- type EdgeShape
- type EdgeVersion
- type ExportFormat
- type GEXFAttValue
- type GEXFAttr
- type GEXFAttrs
- type GEXFDocument
- type GEXFEdge
- type GEXFEdges
- type GEXFGraph
- type GEXFMeta
- type GEXFNode
- type GEXFNodes
- type GraphDiffResult
- type GraphEdge
- type GraphFilter
- type GraphMLData
- type GraphMLDocument
- type GraphMLEdge
- type GraphMLGraph
- type GraphMLKey
- type GraphMLNode
- type GraphNode
- type GraphResult
- type GraphStatistics
- type GraphStore
- func (g *GraphStore) ApplyRules(ctx context.Context, rules []Rule, opts RuleOptions) (*RuleApplyResult, error)
- func (g *GraphStore) ArchiveEdgesTx(ctx context.Context, tx *sql.Tx, edgeIDs []string, at time.Time) error
- func (g *GraphStore) ArchiveNodesTx(ctx context.Context, tx *sql.Tx, nodeIDs []string, at time.Time) error
- func (g *GraphStore) BookkeepingCount(ctx context.Context) (PropertyCount, error)
- func (g *GraphStore) CommunityDetection(ctx context.Context) ([]Community, error)
- func (g *GraphStore) CompactIRI(ctx context.Context, value string) (string, error)
- func (g *GraphStore) Connected(ctx context.Context, nodeID1, nodeID2 string, maxDepth int) (bool, error)
- func (g *GraphStore) Connectivity(ctx context.Context) (Connectivity, error)
- func (g *GraphStore) CountNodes(ctx context.Context, filter *GraphFilter) (int, error)
- func (g *GraphStore) DeleteEdge(ctx context.Context, edgeID string) error
- func (g *GraphStore) DeleteEdgesBatch(ctx context.Context, edgeIDs []string) (*BatchResult, error)
- func (g *GraphStore) DeleteNamespace(ctx context.Context, prefix string) error
- func (g *GraphStore) DeleteNode(ctx context.Context, nodeID string) error
- func (g *GraphStore) DeleteNodesBatch(ctx context.Context, nodeIDs []string) (*BatchResult, error)
- func (g *GraphStore) DeleteRule(ctx context.Context, id string) (bool, error)
- func (g *GraphStore) DeleteTriple(ctx context.Context, triple RDFTriple) error
- func (g *GraphStore) DeleteTriples(ctx context.Context, pattern TriplePattern) (int, error)
- func (g *GraphStore) EdgeEndpointPairs(ctx context.Context, edgeTypes ...string) ([]EdgeEndpointPair, error)
- func (g *GraphStore) EdgeShapes(ctx context.Context, edgeTypes ...string) ([]EdgeShape, error)
- func (g *GraphStore) EdgeSource(ctx context.Context) (string, []any)
- func (g *GraphStore) EdgeTypeCounts(ctx context.Context) (map[string]int, error)
- func (g *GraphStore) EnableHNSWIndex(dimensions int) error
- func (g *GraphStore) ExecuteBatch(ctx context.Context, ops *BatchGraphOperation) (*BatchResult, error)
- func (g *GraphStore) ExecuteBatchTx(ctx context.Context, tx *sql.Tx, ops *BatchGraphOperation) (*BatchResult, error)
- func (g *GraphStore) ExecuteSPARQL(ctx context.Context, query string) (*SPARQLResult, error)
- func (g *GraphStore) ExpandIRI(ctx context.Context, value string) (string, error)
- func (g *GraphStore) ExplainEdge(ctx context.Context, edgeID string) (*RuleEdgeExplanation, error)
- func (g *GraphStore) ExplainEdgeTrace(ctx context.Context, edgeID string, depth int) ([]RuleEdgeTraceEntry, error)
- func (g *GraphStore) ExplainTriple(ctx context.Context, tripleID string) (*RDFSInferenceExplanation, error)
- func (g *GraphStore) ExplainTripleTrace(ctx context.Context, tripleID string, depth int) ([]RDFSInferenceTraceEntry, error)
- func (g *GraphStore) ExplainTriplesByPattern(ctx context.Context, pattern TriplePattern, depth int) ([]RDFSInferenceMatchExplanation, error)
- func (g *GraphStore) Export(ctx context.Context, writer io.Writer, format ExportFormat) error
- func (g *GraphStore) ExportGEXF(ctx context.Context, writer io.Writer) error
- func (g *GraphStore) ExportGraphML(ctx context.Context, writer io.Writer) error
- func (g *GraphStore) ExportJSON(ctx context.Context, writer io.Writer) error
- func (g *GraphStore) ExportRDF(ctx context.Context, writer io.Writer, format RDFFormat) error
- func (g *GraphStore) FindTriples(ctx context.Context, pattern TriplePattern) ([]RDFTriple, error)
- func (g *GraphStore) GetAllNodes(ctx context.Context, filter *GraphFilter) ([]*GraphNode, error)
- func (g *GraphStore) GetEdges(ctx context.Context, nodeID string, direction string) ([]*GraphEdge, error)
- func (g *GraphStore) GetEdgesBatch(ctx context.Context, edgeIDs []string) ([]*GraphEdge, error)
- func (g *GraphStore) GetGraphStatistics(ctx context.Context) (*GraphStatistics, error)
- func (g *GraphStore) GetNode(ctx context.Context, nodeID string) (*GraphNode, error)
- func (g *GraphStore) GetNodesBatch(ctx context.Context, nodeIDs []string) ([]*GraphNode, error)
- func (g *GraphStore) GetRule(ctx context.Context, id string) (*StoredRule, error)
- func (g *GraphStore) GetTriple(ctx context.Context, id string) (*RDFTriple, error)
- func (g *GraphStore) GraphDiff(ctx context.Context, from, to time.Time, opts DiffOptions) (*GraphDiffResult, error)
- func (g *GraphStore) GraphVectorSearch(ctx context.Context, startNodeID string, vector []float32, ...) ([]*HybridResult, error)
- func (g *GraphStore) HNSWHybridSearch(ctx context.Context, query *HybridQuery) ([]*HybridResult, error)
- func (g *GraphStore) HNSWSearch(ctx context.Context, query []float32, k int, threshold float64) ([]*HybridResult, error)
- func (g *GraphStore) HybridSearch(ctx context.Context, query *HybridQuery) ([]*HybridResult, error)
- func (g *GraphStore) Import(ctx context.Context, reader io.Reader, format ExportFormat) error
- func (g *GraphStore) ImportGEXF(ctx context.Context, reader io.Reader) error
- func (g *GraphStore) ImportGraphML(ctx context.Context, reader io.Reader) error
- func (g *GraphStore) ImportJSON(ctx context.Context, reader io.Reader) error
- func (g *GraphStore) ImportRDF(ctx context.Context, reader io.Reader, format RDFFormat) (int, error)
- func (g *GraphStore) InferenceSummary(ctx context.Context) (*RDFSInferenceSummary, error)
- func (g *GraphStore) InitGraphSchema(ctx context.Context) error
- func (g *GraphStore) ListNamespaces(ctx context.Context) ([]Namespace, error)
- func (g *GraphStore) ListNodes(ctx context.Context, filter *GraphFilter) ([]*GraphNode, error)
- func (g *GraphStore) ListRules(ctx context.Context, onlyEnabled bool) ([]StoredRule, error)
- func (g *GraphStore) MergeEntities(ctx context.Context, canonicalID string, aliasIDs []string) error
- func (g *GraphStore) Neighbors(ctx context.Context, nodeID string, opts TraversalOptions) ([]*GraphNode, error)
- func (g *GraphStore) NodeLabels(ctx context.Context, q NodeLabelQuery) ([]NodeLabel, error)
- func (g *GraphStore) NodePropertyKeys(ctx context.Context, nodeTypes ...string) ([]PropertyKeyUsage, error)
- func (g *GraphStore) NodeSource(ctx context.Context) (string, []any)
- func (g *GraphStore) NodeTypeCounts(ctx context.Context) (map[string]int, error)
- func (g *GraphStore) Now() time.Time
- func (g *GraphStore) PageRank(ctx context.Context, iterations int, dampingFactor float64) ([]PageRankResult, error)
- func (g *GraphStore) PredictEdges(ctx context.Context, nodeID string, topK int) ([]EdgePrediction, error)
- func (g *GraphStore) PropertyCounts(ctx context.Context, key string) (map[string]PropertyCount, error)
- func (g *GraphStore) PropertyCountsOfKnowledge(ctx context.Context, key string) (map[string]PropertyCount, error)
- func (g *GraphStore) Purge(ctx context.Context, before time.Time, dryRun bool) (*PurgeReport, error)
- func (g *GraphStore) RecordsWithProperties(ctx context.Context, q PropertyRecordQuery) ([]PropertyRecord, error)
- func (g *GraphStore) RefreshRDFSInferences(ctx context.Context) (*RDFSInferenceRefreshResult, error)
- func (g *GraphStore) RefreshRDFSInferencesIncremental(ctx context.Context, changedTriples []RDFTriple) (*RDFSInferenceRefreshResult, error)
- func (g *GraphStore) RetractEdgeAt(ctx context.Context, edgeID string, at time.Time) error
- func (g *GraphStore) RetractNodeAt(ctx context.Context, nodeID string, at time.Time) error
- func (g *GraphStore) RetractNodes(ctx context.Context, nodeIDs []string) (nodes int, edges int, err error)
- func (g *GraphStore) SPARQLMutates(ctx context.Context, query string) bool
- func (g *GraphStore) SaveRule(ctx context.Context, rule Rule, enabled bool) (*StoredRule, error)
- func (g *GraphStore) ShortestPath(ctx context.Context, fromID, toID string) (*PathResult, error)
- func (g *GraphStore) SimilarityInGraph(ctx context.Context, nodeID string, opts core.SearchOptions) ([]*HybridResult, error)
- func (g *GraphStore) Subgraph(ctx context.Context, nodeIDs []string) (*GraphResult, error)
- func (g *GraphStore) SyncDeletedNodeIDs(_ context.Context, nodeIDs []string)
- func (g *GraphStore) SyncUpsertedNodes(_ context.Context, nodes []*GraphNode)
- func (g *GraphStore) UpsertEdge(ctx context.Context, edge *GraphEdge) error
- func (g *GraphStore) UpsertEdgesBatch(ctx context.Context, edges []*GraphEdge) (*BatchResult, error)
- func (g *GraphStore) UpsertNamespace(ctx context.Context, ns Namespace) error
- func (g *GraphStore) UpsertNode(ctx context.Context, node *GraphNode) error
- func (g *GraphStore) UpsertNodesBatch(ctx context.Context, nodes []*GraphNode) (*BatchResult, error)
- func (g *GraphStore) UpsertTriple(ctx context.Context, triple *RDFTriple) error
- func (g *GraphStore) UpsertTriplesBatch(ctx context.Context, triples []*RDFTriple) (*BatchResult, error)
- func (g *GraphStore) ValidateSHACL(ctx context.Context, shapeTriples []RDFTriple) (*SHACLReport, error)
- type HNSWGraphIndex
- type HybridQuery
- type HybridResult
- type HybridWeights
- type Interval
- type IntervalRelation
- type Namespace
- type NodeChange
- type NodeLabel
- type NodeLabelQuery
- type NodeVersion
- type PageRankResult
- type PathResult
- type PropertyCount
- type PropertyKeyUsage
- type PropertyRecord
- type PropertyRecordQuery
- type PurgeReport
- type RDFFormat
- type RDFSInferenceExplanation
- type RDFSInferenceMatchExplanation
- type RDFSInferenceRefreshResult
- type RDFSInferenceSummary
- type RDFSInferenceTraceEntry
- type RDFTerm
- type RDFTriple
- type ReadOptions
- type Rule
- type RuleApplyResult
- type RuleEdgeExplanation
- type RuleEdgeTraceEntry
- type RuleOptions
- type RuleParseError
- type SHACLReport
- type SHACLValidationResult
- type SPARQLResult
- type SimpleHNSW
- type StoredRule
- type TraversalOptions
- type TriplePattern
Constants ¶
const ( // RDFTermIRI represents an IRI/resource term. RDFTermIRI = "iri" // RDFTermBlankNode represents a blank node term. RDFTermBlankNode = "blank_node" // RDFTermLiteral represents a literal term. RDFTermLiteral = "literal" )
const ( DefaultRuleMaxIterations = 16 DefaultRuleMaxDerived = 50000 )
Default caps for forward chaining.
A rule set is a program, and a program written in a tool call can loop. The caps are what stops one: not a timeout, which would leave whatever it had managed to write behind, but a hard bound after which ApplyRules writes nothing and says why. Sixteen rounds is far more than transitive closure over a real graph needs — closure over n nodes converges in ceil(log2 n) rounds of this naive chaining — and 50k edges is more than any single call should be adding to a brain without somebody having decided to.
const ( SHACLNamespace = "http://www.w3.org/ns/shacl#" RDFNamespace = "http://www.w3.org/1999/02/22-rdf-syntax-ns#" XSDNamespace = "http://www.w3.org/2001/XMLSchema#" SHACLNodeShape = SHACLNamespace + "NodeShape" SHACLPropertyShape = SHACLNamespace + "PropertyShape" SHACLProperty = SHACLNamespace + "property" SHACLPath = SHACLNamespace + "path" SHACLTargetClass = SHACLNamespace + "targetClass" SHACLTargetNode = SHACLNamespace + "targetNode" SHACLDatatype = SHACLNamespace + "datatype" SHACLMinCount = SHACLNamespace + "minCount" SHACLMaxCount = SHACLNamespace + "maxCount" SHACLMinInclusive = SHACLNamespace + "minInclusive" SHACLMaxInclusive = SHACLNamespace + "maxInclusive" SHACLPattern = SHACLNamespace + "pattern" SHACLIn = SHACLNamespace + "in" SHACLNodeKind = SHACLNamespace + "nodeKind" SHACLClass = SHACLNamespace + "class" SHACLSeverity = SHACLNamespace + "severity" SHACLMessage = SHACLNamespace + "message" SHACLSeverityInfo = SHACLNamespace + "Info" SHACLSeverityWarning = SHACLNamespace + "Warning" SHACLSeverityViolation = SHACLNamespace + "Violation" SHACLIRI = SHACLNamespace + "IRI" SHACLBlankNode = SHACLNamespace + "BlankNode" SHACLLiteral = SHACLNamespace + "Literal" SHACLBlankNodeOrIRI = SHACLNamespace + "BlankNodeOrIRI" SHACLBlankNodeOrLiteral = SHACLNamespace + "BlankNodeOrLiteral" SHACLIRIOrLiteral = SHACLNamespace + "IRIOrLiteral" RDFType = RDFNamespace + "type" )
SHACL IRIs
const ( // SPARQLQuerySelect executes a tabular SELECT query. SPARQLQuerySelect = "select" // SPARQLQueryAsk executes a boolean ASK query. SPARQLQueryAsk = "ask" // SPARQLQueryConstruct executes a graph-producing CONSTRUCT query. SPARQLQueryConstruct = "construct" // SPARQLQueryDescribe executes a graph-producing DESCRIBE query. SPARQLQueryDescribe = "describe" // SPARQLQueryInsertData executes an INSERT DATA update. SPARQLQueryInsertData = "insert_data" // SPARQLQueryDeleteData executes a DELETE DATA update. SPARQLQueryDeleteData = "delete_data" // SPARQLQueryDeleteWhere executes a DELETE WHERE update. SPARQLQueryDeleteWhere = "delete_where" // SPARQLQueryModify executes INSERT ... WHERE / DELETE ... INSERT ... WHERE style updates. SPARQLQueryModify = "modify" )
const DefaultRuleExplainDepth = 4
DefaultRuleExplainDepth is how far ExplainEdge follows the support chain when the caller does not say. Derived edges can support other derived edges, so an explanation is a tree, and an unbounded one over a transitive closure is a wall of text nobody reads.
const RuleProvenance = "rule"
RuleProvenance is the provenance value written onto every rule-derived edge. The original two-hop inference wrote it, and it is what tells a reader that a rule and not an extractor put the edge there.
Variables ¶
var ( BookkeepingNodeTypes = []string{"Decision", "chunk", "document"} BookkeepingEdgeTypes = []string{"has_chunk", "mentions", "based_on"} )
BookkeepingNodeTypes and BookkeepingEdgeTypes are the store's own records — the rows that are not claims about the world.
A decision is a graph node so decision_chain can walk it; a chunk and its document are nodes so an entity can cite one; has_chunk, mentions and based_on are the edges that hold all three in place. None of them carries a grade and none of them ever will, because there is nothing to grade: they are how the store remembers rather than what it knows.
Listed rather than derived from "has no grade", which is the test that put them in the untagged column in the first place. Two rows that carry no grade are different findings — one is a fact nobody stamped and the other is a filing cabinet — and a rule that cannot tell them apart reports the cabinet as the problem.
var ErrRuleCapExceeded = errors.New("rule derivation cap exceeded")
ErrRuleCapExceeded reports that forward chaining stopped at a cap instead of at a fixpoint. Nothing is written when it is returned: a half-computed closure in the graph is worse than none, because nothing downstream can tell which half it got.
Functions ¶
func AsOf ¶ added in v2.99.0
AsOf is WithReadOptions for the one field it has.
nodes, err := store.ListNodes(graph.AsOf(ctx, before), nil)
func DerivedEdgeID ¶ added in v2.98.0
DerivedEdgeID is the identity of an edge derived by a rule. It deliberately excludes the premises: one rule concluding the same relation between the same two nodes is one edge, however many chains reach it, so a re-run upserts rather than accumulating near-duplicates.
func IsRuleVariable ¶ added in v2.98.0
IsRuleVariable reports whether a term is a variable rather than a literal.
func NotInTypes ¶ added in v2.110.0
NotInTypes renders "this column is none of these types", for the queries that have to leave the store's own filing out.
Exported because two packages ask the same question and the answer has to be the same one: the tally counts the knowledge in a brain and the live graph draws it, and a picture that included a Decision node while the panel beside it did not count one would be two views of the same store that disagree.
Values are spelled into the SQL rather than bound. They are this package's own constants — nothing here comes from a caller — and threading a variable number of arguments through queries that already bind their own would put the ordering of those arguments at risk for no gain.
func WithReadOptions ¶ added in v2.99.0
func WithReadOptions(ctx context.Context, opts ReadOptions) context.Context
WithReadOptions returns a context whose graph reads answer at opts.AsOf.
Types ¶
type AllenRelation ¶ added in v2.99.0
type AllenRelation string
AllenRelation names how one interval sits against another.
const ( AllenBefore AllenRelation = "before" // a ends strictly before b starts AllenAfter AllenRelation = "after" // inverse of before AllenMeets AllenRelation = "meets" // a ends exactly where b starts AllenMetBy AllenRelation = "met_by" // inverse of meets AllenOverlaps AllenRelation = "overlaps" // a starts first, they share a stretch, a ends first AllenOverlappedBy AllenRelation = "overlapped_by" // inverse of overlaps AllenStarts AllenRelation = "starts" // same start, a ends first AllenStartedBy AllenRelation = "started_by" // inverse of starts AllenDuring AllenRelation = "during" // a sits strictly inside b AllenContains AllenRelation = "contains" // inverse of during AllenFinishes AllenRelation = "finishes" // same end, a starts later AllenFinishedBy AllenRelation = "finished_by" // inverse of finishes AllenEquals AllenRelation = "equals" // same start and same end // AllenUndefined is returned for an interval that spans nothing. Not an // error return: the caller of a diff wants the pairs it can name and the // ones it cannot, not a failed query because one row was degenerate. AllenUndefined AllenRelation = "" )
The thirteen, in inverse pairs plus equals. The names are Allen's; the direction is always "a is <relation> b".
func Relate ¶ added in v2.99.0
func Relate(a, b Interval) AllenRelation
Relate names how a sits against b. Exactly one relation holds for any two intervals that span anything, which is the property the whole algebra rests on and the reason the switch below has no default case that means "several".
func (AllenRelation) Inverse ¶ added in v2.99.0
func (r AllenRelation) Inverse() AllenRelation
Inverse returns the relation that holds in the other direction, so a caller holding `a overlaps b` can state `b overlapped_by a` without recomputing.
type Atom ¶ added in v2.98.0
type Atom struct {
Predicate string `json:"predicate"`
Subject string `json:"subject"`
Object string `json:"object"`
}
Atom is one edge pattern: predicate(subject, object).
A term starting with '?' is a variable. Anything else is a literal, resolved against the stored nodes — see ResolveRuleTerm for exactly how, because "matches a node" is the one part of this that a caller has to be told rather than able to guess.
type BatchEdgeOperation ¶
type BatchEdgeOperation struct {
Edges []*GraphEdge
}
BatchEdgeOperation represents a batch operation for edges
type BatchGraphOperation ¶
type BatchGraphOperation struct {
NodeUpserts []*GraphNode
NodeDeletes []string
EdgeUpserts []*GraphEdge
EdgeDeletes []string
}
BatchGraphOperation allows multiple graph operations in a single transaction
type BatchNodeOperation ¶
type BatchNodeOperation struct {
Nodes []*GraphNode
}
BatchNodeOperation represents a batch operation for nodes
type BatchResult ¶
BatchResult contains the results of a batch operation.
A batch is partial by design: one rejected row does not roll the others back, so the batch functions report per-row failures here and reserve their error return for failures of the batch itself (transaction, prepare, commit). That makes it easy to lose writes without noticing — a caller that only checks err sees success for a batch in which every row was rejected. Call Err to fold the per-row failures back into a normal error before reporting success upwards.
func (*BatchResult) Err ¶ added in v2.69.0
func (r *BatchResult) Err() error
Err returns the per-row failures of a batch joined into a single error, or nil when every row the caller supplied was written.
Only rows that actually failed are reported: the delete batches count ids that matched nothing as failed without recording an error, because "not there" is not a failure to delete. The upsert batches record an error for every failure they count.
type Community ¶
type Community struct {
ID int `json:"id"`
Nodes []string `json:"nodes"`
Score float64 `json:"score"` // Modularity score
}
Community represents a detected community of nodes
type Connectivity ¶ added in v2.86.0
Connectivity is how much of the graph an edge can reach.
type DiffKind ¶ added in v2.99.0
type DiffKind string
DiffKind is why a row is in the diff.
const ( // DiffAdded: present at `to`, absent at `from`. DiffAdded DiffKind = "added" // DiffRetracted: present at `from`, absent at `to`. Retracted rather than // deleted, because that is what it is now — the row is still readable at // any instant before it went. DiffRetracted DiffKind = "retracted" // DiffChanged: present at both, saying something different. DiffChanged DiffKind = "changed" )
type DiffOptions ¶ added in v2.99.0
type DiffOptions struct {
// Limit caps each of the two lists. Zero means 100; a diff is a report, and
// an unbounded one is a report nobody reads and a response nobody can pass
// to a model.
Limit int
// Cursor continues a previous diff. It is the last id that page emitted;
// nodes and edges are paged together by the same id, which is safe because
// both streams are ordered by it.
Cursor string
// NodeTypes and EdgeTypes narrow the diff to a kind of thing.
NodeTypes []string
EdgeTypes []string
// MaxIntervalPairs caps the Allen relations reported. Zero means 50.
MaxIntervalPairs int
}
DiffOptions bounds a diff.
type EdgeChange ¶ added in v2.99.0
type EdgeChange struct {
ID string `json:"id"`
Kind DiffKind `json:"kind"`
Before *EdgeVersion `json:"before,omitempty"`
After *EdgeVersion `json:"after,omitempty"`
}
type EdgeEndpoint ¶ added in v2.85.0
type EdgeEndpoint struct {
ID string `json:"id"`
NodeType string `json:"node_type"`
Content string `json:"content"`
}
EdgeEndpoint identifies one end of an edge, with enough about the node to name it in a report without a second round trip.
type EdgeEndpointPair ¶ added in v2.85.0
type EdgeEndpointPair struct {
EdgeType string `json:"edge_type"`
From EdgeEndpoint `json:"from"`
To EdgeEndpoint `json:"to"`
Count int `json:"count"`
}
EdgeEndpointPair is one (edge type, from node, to node) combination and how many edges join exactly those two nodes with that type.
type EdgePrediction ¶
type EdgePrediction struct {
FromNodeID string `json:"from_node_id"`
ToNodeID string `json:"to_node_id"`
Score float64 `json:"score"`
Method string `json:"method"`
}
EdgePrediction represents a predicted edge with confidence score
type EdgeShape ¶ added in v2.85.0
type EdgeShape struct {
EdgeType string `json:"edge_type"`
FromType string `json:"from_type"`
ToType string `json:"to_type"`
Count int `json:"count"`
}
EdgeShape is one (edge type, from-node type, to-node type) combination present in the graph, and how many edges have it.
type EdgeVersion ¶ added in v2.99.0
type EdgeVersion struct {
ID string `json:"id"`
From string `json:"from"`
To string `json:"to"`
EdgeType string `json:"edge_type,omitempty"`
Weight float64 `json:"weight,omitempty"`
Properties string `json:"properties,omitempty"`
ValidFrom time.Time `json:"valid_from,omitzero"`
ValidTo time.Time `json:"valid_to,omitzero"`
}
EdgeVersion is an edge as it stood at one instant.
func (EdgeVersion) Interval ¶ added in v2.99.0
func (v EdgeVersion) Interval() Interval
Interval is this version's validity, for Relate.
type ExportFormat ¶
type ExportFormat string
ExportFormat represents supported export formats
const ( FormatGraphML ExportFormat = "graphml" FormatGEXF ExportFormat = "gexf" FormatJSON ExportFormat = "json" )
func DetectFormat ¶
func DetectFormat(reader io.Reader) (ExportFormat, error)
DetectFormat attempts to detect the format of the input
type GEXFAttValue ¶
GEXFAttValue represents a GEXF attribute value
type GEXFAttr ¶
type GEXFAttr struct {
ID string `xml:"id,attr"`
Title string `xml:"title,attr"`
Type string `xml:"type,attr"`
}
GEXFAttr represents a GEXF attribute
type GEXFDocument ¶
type GEXFDocument struct {
XMLName xml.Name `xml:"gexf"`
XMLNS string `xml:"xmlns,attr"`
Version string `xml:"version,attr"`
Meta GEXFMeta `xml:"meta"`
Graph GEXFGraph `xml:"graph"`
}
GEXFDocument represents a GEXF document
type GEXFEdge ¶
type GEXFEdge struct {
ID string `xml:"id,attr"`
Source string `xml:"source,attr"`
Target string `xml:"target,attr"`
Weight float64 `xml:"weight,attr,omitempty"`
Type string `xml:"type,attr,omitempty"`
}
GEXFEdge represents a GEXF edge
type GEXFEdges ¶
type GEXFEdges struct {
Edges []GEXFEdge `xml:"edge"`
}
GEXFEdges represents GEXF edges container
type GEXFGraph ¶
type GEXFGraph struct {
Mode string `xml:"mode,attr"`
DefaultEdgeType string `xml:"defaultedgetype,attr"`
Attributes GEXFAttrs `xml:"attributes"`
Nodes GEXFNodes `xml:"nodes"`
Edges GEXFEdges `xml:"edges"`
}
GEXFGraph represents a GEXF graph
type GEXFNode ¶
type GEXFNode struct {
ID string `xml:"id,attr"`
Label string `xml:"label,attr"`
AttValues []GEXFAttValue `xml:"attvalues>attvalue"`
}
GEXFNode represents a GEXF node
type GEXFNodes ¶
type GEXFNodes struct {
Nodes []GEXFNode `xml:"node"`
}
GEXFNodes represents GEXF nodes container
type GraphDiffResult ¶ added in v2.99.0
type GraphDiffResult struct {
From time.Time `json:"from"`
To time.Time `json:"to"`
Nodes []NodeChange `json:"nodes"`
Edges []EdgeChange `json:"edges"`
// NextCursor is non-empty when the limit cut the walk short. Pass it back
// as DiffOptions.Cursor.
NextCursor string `json:"next_cursor,omitempty"`
Truncated bool `json:"truncated,omitempty"`
// IntervalRelations names how the changed edges about one subject sit
// against each other in time — which is where "the runbook's claim ended
// when the incident's began" comes from, instead of two rows of timestamps
// a reader has to compare by eye.
IntervalRelations []IntervalRelation `json:"interval_relations,omitempty"`
}
GraphDiffResult is what changed, and how the changed facts sit in time.
type GraphEdge ¶
type GraphEdge struct {
ID string `json:"id"`
FromNodeID string `json:"from_node_id"`
ToNodeID string `json:"to_node_id"`
EdgeType string `json:"edge_type,omitempty"`
Weight float64 `json:"weight"`
Properties map[string]interface{} `json:"properties,omitempty"`
Vector []float32 `json:"vector,omitempty"` // Optional edge embedding
CreatedAt time.Time `json:"created_at"`
// The bitemporal columns, with the same rules as GraphNode's: ValidFrom is
// an input, the other three are outputs. An edge is where these earn their
// keep — "the runbook recommended sds-meta" is a claim with a beginning and
// an end, and Relate names how two such claims sit against each other.
ValidFrom time.Time `json:"valid_from,omitzero"`
ValidTo time.Time `json:"valid_to,omitzero"`
RecordedAt time.Time `json:"recorded_at,omitzero"`
RetractedAt time.Time `json:"retracted_at,omitzero"`
}
GraphEdge represents a directed edge between two nodes
type GraphFilter ¶
type GraphFilter struct {
NodeTypes []string `json:"node_types,omitempty"`
EdgeTypes []string `json:"edge_types,omitempty"`
MaxDepth int `json:"max_depth,omitempty"`
// Properties scopes a query to nodes whose properties JSON carries every
// one of these top-level string fields with these values.
//
// It exists because a store this one shares with everything else on the
// machine had no way to ask for one importer's rows. node_type was the
// only filter, and a type name is not a batch: an importer that wrote a
// thousand Person nodes on Tuesday and a thousand more on Friday could
// not ask for either set, only for all two thousand. Every writer that
// cared already stamped a batch onto properties — alchemy's connector
// writes "run" — and nothing could read it back.
//
// The fields are ANDed, and each is compared as text: properties is a
// JSON object serialized by json.Marshal, and the guarded read in
// pkg/sqldialect is what keeps a row with no properties at all from
// failing the whole query rather than simply not matching.
Properties map[string]string `json:"properties,omitempty"`
// Contains narrows to nodes whose property holds this text somewhere in
// it, compared case-insensitively and ANDed with everything else.
//
// Separate from Properties because the two are different questions and
// only one of them can use an index: Properties is how a caller names a
// batch it already knows, Contains is how a search enters the graph at
// all. Folding them into one map would make every batch scope a LIKE.
//
// The value is matched literally — % and _ in it mean those characters,
// not wildcards — because the text comes from whoever typed the query and
// a name with an underscore in it is ordinary.
Contains map[string]string `json:"contains,omitempty"`
// Limit caps the rows a query returns. Zero means no cap, which is what
// every caller before this field got and still gets.
//
// A cap alone would be worse than none: a caller shown 100 of 4000 rows
// with nothing saying so reports 100. CountNodes answers the other half,
// and the two are meant to be used together.
Limit int `json:"limit,omitempty"`
}
GraphFilter defines filtering options for graph queries
type GraphMLData ¶
GraphMLData represents GraphML data
type GraphMLDocument ¶
type GraphMLDocument struct {
XMLName xml.Name `xml:"graphml"`
XMLNS string `xml:"xmlns,attr"`
Keys []GraphMLKey `xml:"key"`
Graph GraphMLGraph `xml:"graph"`
}
GraphMLDocument represents a GraphML document
type GraphMLEdge ¶
type GraphMLEdge struct {
ID string `xml:"id,attr"`
Source string `xml:"source,attr"`
Target string `xml:"target,attr"`
Data []GraphMLData `xml:"data"`
}
GraphMLEdge represents a GraphML edge
type GraphMLGraph ¶
type GraphMLGraph struct {
ID string `xml:"id,attr"`
EdgeDefault string `xml:"edgedefault,attr"`
Nodes []GraphMLNode `xml:"node"`
Edges []GraphMLEdge `xml:"edge"`
}
GraphMLGraph represents a GraphML graph
type GraphMLKey ¶
type GraphMLKey struct {
ID string `xml:"id,attr"`
For string `xml:"for,attr"`
AttrName string `xml:"attr.name,attr"`
AttrType string `xml:"attr.type,attr"`
}
GraphMLKey represents a GraphML key definition
type GraphMLNode ¶
type GraphMLNode struct {
ID string `xml:"id,attr"`
Data []GraphMLData `xml:"data"`
}
GraphMLNode represents a GraphML node
type GraphNode ¶
type GraphNode struct {
ID string `json:"id"`
Vector []float32 `json:"vector"`
Content string `json:"content,omitempty"`
NodeType string `json:"node_type,omitempty"`
Properties map[string]interface{} `json:"properties,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
// The bitemporal columns. See pkg/graph/temporal.go for what the two axes
// mean and why NULL is unbounded on all four.
//
// ValidFrom is the only one a caller may set on a write: it says when the
// fact became true in the world, and defaults to the moment of the write.
// The other three are set by the store and ignored on write, the same way
// CreatedAt and UpdatedAt already were — a live row always has an open
// ValidTo and no RetractedAt, because a row that has ended or been
// retracted lives in graph_node_history instead.
ValidFrom time.Time `json:"valid_from,omitzero"`
ValidTo time.Time `json:"valid_to,omitzero"`
RecordedAt time.Time `json:"recorded_at,omitzero"`
RetractedAt time.Time `json:"retracted_at,omitzero"`
}
GraphNode represents a node in the graph with vector embedding
type GraphResult ¶
GraphResult represents a subgraph or query result
type GraphStatistics ¶
type GraphStatistics struct {
NodeCount int `json:"node_count"`
EdgeCount int `json:"edge_count"`
AverageDegree float64 `json:"average_degree"`
Density float64 `json:"density"`
ConnectedComponents int `json:"connected_components"`
}
GraphStatistics represents overall graph statistics
type GraphStore ¶
type GraphStore struct {
// contains filtered or unexported fields
}
GraphStore provides graph operations on top of the vector store
func NewGraphStore ¶
func NewGraphStore(s *core.SQLiteStore) *GraphStore
NewGraphStore creates a new graph store from a SQLite store.
func NewGraphStoreOn ¶ added in v2.82.0
func NewGraphStoreOn(db *sql.DB, d sqldialect.Dialect, host vectorHost) *GraphStore
NewGraphStoreOn creates a graph store over any database this dialect can speak, for a host that supplies the vector-side settings.
The same tables and the same queries as NewGraphStore — the graph layer has no SQLite-only SQL in it, which is what makes one implementation over two databases possible rather than two implementations to keep in step.
func (*GraphStore) ApplyRules ¶ added in v2.98.0
func (g *GraphStore) ApplyRules(ctx context.Context, rules []Rule, opts RuleOptions) (*RuleApplyResult, error)
ApplyRules forward-chains rules over the stored graph to a fixpoint and materializes what it derives.
Every derived edge carries inferred=true, provenance=rule, the rule's id and text, the exact premise edge ids, and a confidence that is the minimum of the premise confidences times the rule's own — the same provenance the two-hop inference wrote, which is what lets ExplainEdge explain either.
A run that hits a cap writes nothing and returns ErrRuleCapExceeded along with a result whose CapReason says which cap. Both are returned: the error is what a caller cannot ignore, the result is what tells them why.
func (*GraphStore) ArchiveEdgesTx ¶ added in v2.99.0
func (g *GraphStore) ArchiveEdgesTx(ctx context.Context, tx *sql.Tx, edgeIDs []string, at time.Time) error
ArchiveEdgesTx is ArchiveNodesTx for edges the caller deletes itself.
func (*GraphStore) ArchiveNodesTx ¶ added in v2.99.0
func (g *GraphStore) ArchiveNodesTx(ctx context.Context, tx *sql.Tx, nodeIDs []string, at time.Time) error
ArchiveNodesTx moves nodes and every edge touching them into history with retracted_at set, without deleting anything.
Exported and transaction-taking for the one caller shape that cannot use RetractNodes: pkg/cortexdb deletes a document's whole graph inside a transaction of its own, and splitting the archive out of that transaction would make a crash between them lose the history of rows that did get deleted. Call it immediately before the DELETE, in the same transaction.
Edges go with the node because a retracted node's edges are retracted too — graph_edges has ON DELETE CASCADE on both ends, so the DELETE that follows removes them whether or not the caller listed them, and an edge deleted with no history row is a fact that vanished.
func (*GraphStore) BookkeepingCount ¶ added in v2.110.0
func (g *GraphStore) BookkeepingCount(ctx context.Context) (PropertyCount, error)
BookkeepingCount counts them.
func (*GraphStore) CommunityDetection ¶
func (g *GraphStore) CommunityDetection(ctx context.Context) ([]Community, error)
CommunityDetection performs community detection using the Louvain method Optimized to reduce DB queries.
func (*GraphStore) CompactIRI ¶ added in v2.16.0
CompactIRI compacts an IRI using the longest matching namespace prefix when available.
func (*GraphStore) Connected ¶
func (g *GraphStore) Connected(ctx context.Context, nodeID1, nodeID2 string, maxDepth int) (bool, error)
Connected checks if two nodes are connected within a given depth
func (*GraphStore) Connectivity ¶ added in v2.86.0
func (g *GraphStore) Connectivity(ctx context.Context) (Connectivity, error)
Connectivity counts the nodes no edge touches, alongside the total.
A large share of orphans means writes landed and their edges did not — the state a store reaches when an ingest's edges are rejected, or when entities accumulate across re-ingests with nothing joining them. Retrieval still finds these nodes and expansion never leaves them, so the graph half of GraphRAG quietly stops contributing while every count still grows.
Both numbers come from one statement so they describe one graph. Asked separately, a write between them yields a share that was never true — and this is a health check, whose whole output is that ratio.
Distinct from GraphStatistics.ConnectedComponents, which asks how the reachable part is divided; this asks how much of the graph is reachable at all.
func (*GraphStore) CountNodes ¶ added in v2.89.0
func (g *GraphStore) CountNodes(ctx context.Context, filter *GraphFilter) (int, error)
CountNodes reports how many nodes match a filter, ignoring its Limit.
It is the other half of GraphFilter.Limit and it is not optional decoration. A caller that asks for 100 nodes and is handed 100 has learned nothing about whether there were 100 or 4000, and the honest failure — "showing 100 of 4000" — is unavailable without this. Callers that report a total to a person or to a model should ask for both.
Limit is ignored on purpose: a count that stopped at the cap would always equal the cap, which is the exact non-answer this method exists to replace.
func (*GraphStore) DeleteEdge ¶
func (g *GraphStore) DeleteEdge(ctx context.Context, edgeID string) error
DeleteEdge removes an edge from the current graph.
A retraction, like DeleteNode: the row moves to graph_edge_history with retracted_at set, so "what did this fact say before we withdrew it" has an answer and FactProvenanceFor can still resolve it as of an earlier instant. Current reads see exactly what they saw before.
func (*GraphStore) DeleteEdgesBatch ¶
func (g *GraphStore) DeleteEdgesBatch(ctx context.Context, edgeIDs []string) (*BatchResult, error)
DeleteEdgesBatch deletes multiple edges in a single transaction
func (*GraphStore) DeleteNamespace ¶ added in v2.16.0
func (g *GraphStore) DeleteNamespace(ctx context.Context, prefix string) error
DeleteNamespace removes one user-defined namespace mapping.
func (*GraphStore) DeleteNode ¶
func (g *GraphStore) DeleteNode(ctx context.Context, nodeID string) error
DeleteNode removes a node and all its edges from the current graph.
It is a retraction now, not a hard delete: the node and its edges move to graph_node_history / graph_edge_history with retracted_at set, so a read as of any instant before this one still sees them. Every current read is unaffected — the live tables no longer hold the row — which is why the name, the signature and the "node not found" error are all unchanged.
RetractNodeAt is the same operation with the instant stated, for a fact discovered today to have stopped being believed last Tuesday. Purge is the only thing that removes any of it for good.
func (*GraphStore) DeleteNodesBatch ¶
func (g *GraphStore) DeleteNodesBatch(ctx context.Context, nodeIDs []string) (*BatchResult, error)
DeleteNodesBatch deletes multiple nodes in a single transaction
func (*GraphStore) DeleteRule ¶ added in v2.98.0
DeleteRule removes a stored rule and reports whether there was one.
It does not touch the edges that rule derived. Deleting a rule is a statement about what will be derived next time, not a retraction of what is already in the graph — and the derived edges carry the rule text with them, so they remain explicable after the rule is gone.
func (*GraphStore) DeleteTriple ¶ added in v2.16.0
func (g *GraphStore) DeleteTriple(ctx context.Context, triple RDFTriple) error
DeleteTriple removes one RDF triple/quad by its normalized content.
func (*GraphStore) DeleteTriples ¶ added in v2.16.0
func (g *GraphStore) DeleteTriples(ctx context.Context, pattern TriplePattern) (int, error)
DeleteTriples removes all triples matched by the given pattern.
func (*GraphStore) EdgeEndpointPairs ¶ added in v2.85.0
func (g *GraphStore) EdgeEndpointPairs(ctx context.Context, edgeTypes ...string) ([]EdgeEndpointPair, error)
EdgeEndpointPairs reports which nodes the edges of each type actually run between.
EdgeShapes groups by type, which answers "how is this relation wrong" and not "what is wrong". On a live base eighteen non-conforming edges came from thirteen nodes, two of which carried six between them — six edges, two places to look. Getting from one answer to the other needs the nodes, and getting the nodes needs their identity, which is why this returns content and type alongside the id rather than a list of ids to look up afterwards.
Ordering, filtering, and the treatment of missing endpoints are the same as EdgeShapes. This scans one row per distinct (type, from, to) triple, so on a large graph pass the edge types the caller actually cares about.
func (*GraphStore) EdgeShapes ¶ added in v2.85.0
EdgeShapes reports the type shapes the graph's edges actually have.
This is what makes a declared relation checkable. An extracted `backs` asserted from the resource to the pool is stored without complaint, reads as a fact, and is walked as one; nothing in the answer it produces says the arrow points the wrong way. Comparing these shapes against the declared ends is the only thing that can disagree with it.
Passing edge types narrows the scan to those; passing none reports every shape in the graph. They are matched exactly, as stored — the same rule the traversal filters use, since the type in the graph is whatever the extracting model emitted and this package nowhere decides what a near-miss means.
Edges whose endpoints are missing are not reported: both endpoints are declared foreign keys, so on a store this package opened they cannot exist.
func (*GraphStore) EdgeSource ¶ added in v2.99.0
func (g *GraphStore) EdgeSource(ctx context.Context) (string, []any)
func (*GraphStore) EdgeTypeCounts ¶ added in v2.85.0
EdgeTypeCounts returns how many edges carry each edge_type, with untyped edges under the empty string for the same reason as NodeTypeCounts.
func (*GraphStore) EnableHNSWIndex ¶
func (g *GraphStore) EnableHNSWIndex(dimensions int) error
EnableHNSWIndex enables HNSW indexing for the graph store
func (*GraphStore) ExecuteBatch ¶
func (g *GraphStore) ExecuteBatch(ctx context.Context, ops *BatchGraphOperation) (*BatchResult, error)
ExecuteBatch executes multiple graph operations in a single transaction
func (*GraphStore) ExecuteBatchTx ¶ added in v2.14.1
func (g *GraphStore) ExecuteBatchTx(ctx context.Context, tx *sql.Tx, ops *BatchGraphOperation) (*BatchResult, error)
ExecuteBatchTx applies a batch of graph operations inside an existing transaction.
func (*GraphStore) ExecuteSPARQL ¶ added in v2.16.0
func (g *GraphStore) ExecuteSPARQL(ctx context.Context, query string) (*SPARQLResult, error)
ExecuteSPARQL runs a practical SPARQL SELECT/ASK subset against the embedded RDF layer.
func (*GraphStore) ExpandIRI ¶ added in v2.16.0
ExpandIRI expands a compact IRI using registered namespaces when possible.
func (*GraphStore) ExplainEdge ¶ added in v2.98.0
func (g *GraphStore) ExplainEdge(ctx context.Context, edgeID string) (*RuleEdgeExplanation, error)
ExplainEdge returns the immediate derivation of one edge: whether it was inferred, by which rule, and which edges it stands on.
func (*GraphStore) ExplainEdgeTrace ¶ added in v2.98.0
func (g *GraphStore) ExplainEdgeTrace(ctx context.Context, edgeID string, depth int) ([]RuleEdgeTraceEntry, error)
ExplainEdgeTrace follows the premise chain up to depth levels and returns it flattened in preorder. Depth zero means DefaultRuleExplainDepth.
func (*GraphStore) ExplainTriple ¶ added in v2.16.0
func (g *GraphStore) ExplainTriple(ctx context.Context, tripleID string) (*RDFSInferenceExplanation, error)
ExplainTriple returns whether a triple is explicit or inferred and its immediate provenance.
func (*GraphStore) ExplainTripleTrace ¶ added in v2.16.0
func (g *GraphStore) ExplainTripleTrace(ctx context.Context, tripleID string, depth int) ([]RDFSInferenceTraceEntry, error)
ExplainTripleTrace recursively expands provenance for a triple into a flattened trace list.
func (*GraphStore) ExplainTriplesByPattern ¶ added in v2.18.0
func (g *GraphStore) ExplainTriplesByPattern(ctx context.Context, pattern TriplePattern, depth int) ([]RDFSInferenceMatchExplanation, error)
ExplainTriplesByPattern expands explanations for all triples matched by the given pattern.
func (*GraphStore) Export ¶
func (g *GraphStore) Export(ctx context.Context, writer io.Writer, format ExportFormat) error
Export exports the graph in the specified format
func (*GraphStore) ExportGEXF ¶
ExportGEXF exports the graph to GEXF format
func (*GraphStore) ExportGraphML ¶
ExportGraphML exports the graph to GraphML format
func (*GraphStore) ExportJSON ¶
ExportJSON exports the graph to JSON format
func (*GraphStore) ExportRDF ¶ added in v2.16.0
ExportRDF writes triples in the requested RDF format.
func (*GraphStore) FindTriples ¶ added in v2.16.0
func (g *GraphStore) FindTriples(ctx context.Context, pattern TriplePattern) ([]RDFTriple, error)
FindTriples queries triples by pattern.
func (*GraphStore) GetAllNodes ¶
func (g *GraphStore) GetAllNodes(ctx context.Context, filter *GraphFilter) ([]*GraphNode, error)
GetAllNodes retrieves all nodes with optional filtering
func (*GraphStore) GetEdges ¶
func (g *GraphStore) GetEdges(ctx context.Context, nodeID string, direction string) ([]*GraphEdge, error)
GetEdges retrieves edges for a node.
Ordered by id, which matters more than it looks: this feeds Neighbors, and Neighbors feeds graph-mode retrieval. Without an ORDER BY, SQLite happens to return insertion order while PostgreSQL returns whatever the plan produced — so the same question could retrieve a different set of chunks on the two backends, and a different set on PostgreSQL from one run to the next once the table had been updated.
func (*GraphStore) GetEdgesBatch ¶
GetEdgesBatch retrieves multiple edges by their IDs
func (*GraphStore) GetGraphStatistics ¶
func (g *GraphStore) GetGraphStatistics(ctx context.Context) (*GraphStatistics, error)
GetGraphStatistics computes statistics about the graph
func (*GraphStore) GetNodesBatch ¶
GetNodesBatch retrieves multiple nodes by their IDs.
The result contains only the ids that exist, in no guaranteed order, which is what it always did — chunking does not change that contract.
func (*GraphStore) GetRule ¶ added in v2.98.0
func (g *GraphStore) GetRule(ctx context.Context, id string) (*StoredRule, error)
GetRule returns one stored rule, or nil when there is no such rule.
func (*GraphStore) GraphDiff ¶ added in v2.99.0
func (g *GraphStore) GraphDiff(ctx context.Context, from, to time.Time, opts DiffOptions) (*GraphDiffResult, error)
GraphDiff reports what the graph gained, lost and changed between two instants.
Both instants are read through the same as-of machinery as any other past read, so a diff and a pair of snapshots can never disagree. `from` after `to` is refused rather than silently swapped: a caller that has them backwards is asking a different question than the one it would get.
func (*GraphStore) GraphVectorSearch ¶
func (g *GraphStore) GraphVectorSearch(ctx context.Context, startNodeID string, vector []float32, opts TraversalOptions) ([]*HybridResult, error)
GraphVectorSearch performs vector search within a graph neighborhood
func (*GraphStore) HNSWHybridSearch ¶
func (g *GraphStore) HNSWHybridSearch(ctx context.Context, query *HybridQuery) ([]*HybridResult, error)
HNSWHybridSearch combines HNSW search with graph proximity
func (*GraphStore) HNSWSearch ¶
func (g *GraphStore) HNSWSearch(ctx context.Context, query []float32, k int, threshold float64) ([]*HybridResult, error)
HNSWSearch performs HNSW-accelerated vector search
func (*GraphStore) HybridSearch ¶
func (g *GraphStore) HybridSearch(ctx context.Context, query *HybridQuery) ([]*HybridResult, error)
HybridSearch performs a combined vector and graph search
func (*GraphStore) Import ¶
func (g *GraphStore) Import(ctx context.Context, reader io.Reader, format ExportFormat) error
Import imports a graph in the specified format
func (*GraphStore) ImportGEXF ¶
ImportGEXF imports a graph from GEXF format
func (*GraphStore) ImportGraphML ¶
ImportGraphML imports a graph from GraphML format
func (*GraphStore) ImportJSON ¶
ImportJSON imports a graph from JSON format
func (*GraphStore) ImportRDF ¶ added in v2.16.0
func (g *GraphStore) ImportRDF(ctx context.Context, reader io.Reader, format RDFFormat) (int, error)
ImportRDF parses and stores triples from supported RDF serializations.
func (*GraphStore) InferenceSummary ¶ added in v2.18.0
func (g *GraphStore) InferenceSummary(ctx context.Context) (*RDFSInferenceSummary, error)
InferenceSummary returns explicit/inferred counts and an inference-rule breakdown.
func (*GraphStore) InitGraphSchema ¶
func (g *GraphStore) InitGraphSchema(ctx context.Context) error
InitGraphSchema creates the graph tables if they don't exist.
It is cheap to call repeatedly: after the first success this store remembers that its schema is ready and returns without touching SQLite, so write paths can guard themselves with it instead of trusting the caller to have done so.
func (*GraphStore) ListNamespaces ¶ added in v2.16.0
func (g *GraphStore) ListNamespaces(ctx context.Context) ([]Namespace, error)
ListNamespaces returns built-in and user-defined namespaces.
func (*GraphStore) ListNodes ¶ added in v2.90.0
func (g *GraphStore) ListNodes(ctx context.Context, filter *GraphFilter) ([]*GraphNode, error)
ListNodes is GetAllNodes without the vectors.
The projection is the whole of it, and it is not a micro-optimisation. A vector is the largest column on a node — 768 floats is three kilobytes — and GetAllNodes selects it, decodes it, and hands it to a caller that mostly wants to know what things are called. Enumerating the types in a four-hundred-thousand-node import through GetAllNodes moves a gigabyte of embeddings across the driver and decodes every one of them to count names.
It shares nodeWhere with GetAllNodes and CountNodes, so all three are always about the same rows: a list, a count and a filtered read that disagreed about what matched would be worse than any one of them alone.
Nodes come back with a nil Vector. That is the honest shape — a zero-length vector read from a store that holds one would be a lie about the record, and a caller who needs it has GetAllNodes or GetNode.
func (*GraphStore) ListRules ¶ added in v2.98.0
func (g *GraphStore) ListRules(ctx context.Context, onlyEnabled bool) ([]StoredRule, error)
ListRules returns the stored rules in id order. Passing onlyEnabled skips the ones somebody has switched off without deleting.
func (*GraphStore) MergeEntities ¶ added in v2.26.0
func (g *GraphStore) MergeEntities(ctx context.Context, canonicalID string, aliasIDs []string) error
MergeEntities collapses surface-form duplicate nodes into one canonical node: every edge referencing an alias is repointed to canonicalID, self-loops created by the merge are dropped, and the alias nodes are deleted. Used for entity resolution (e.g. unifying "r0" / "DRBD resource" / "resources" into one entity).
func (*GraphStore) Neighbors ¶
func (g *GraphStore) Neighbors(ctx context.Context, nodeID string, opts TraversalOptions) ([]*GraphNode, error)
Neighbors performs a breadth-first search to find neighboring nodes
func (*GraphStore) NodeLabels ¶ added in v2.86.0
func (g *GraphStore) NodeLabels(ctx context.Context, q NodeLabelQuery) ([]NodeLabel, error)
NodeLabels lists nodes with their type and label.
The question behind it is "what is in here, called what" — which spellings a vocabulary actually produced, whether one concept arrived under two names, which labels are long enough to match text against. Callers were reading graph_nodes for it directly, and pairing a schema they are not promised with an id convention they are not promised either.
Ordered by id so two runs over one graph agree, and so a caller paging with Limit sees a stable sequence rather than whichever rows the planner returned first.
func (*GraphStore) NodePropertyKeys ¶ added in v2.94.0
func (g *GraphStore) NodePropertyKeys(ctx context.Context, nodeTypes ...string) ([]PropertyKeyUsage, error)
NodePropertyKeys reports which property keys the nodes of each type carry.
Every other property query in this file starts from a key the caller already knows. This one starts from nothing, because that is where anything deriving a shape from stored data has to start: what the records say about themselves, before anybody has written down what they were supposed to say. A caller wanting it had to enumerate JSON keys itself — which is json_each on SQLite and a lateral jsonb_each_text on PostgreSQL, so it was also a caller pinned to one database.
Passing node types narrows the scan to those; passing none reports every type in the graph. They are matched exactly, as stored, and untyped nodes come back under the empty string — the same two rules NodeTypeCounts and EdgeShapes follow, and for the same reasons.
Domain-neutral, like the rest of this section: it knows that properties is a JSON object of string fields, and nothing about what any key means or what anybody intends to do with the answer.
One row per (type, key) pair, so the cost is a scan of graph_nodes and its properties rather than a scan per type. Ordered by type then key so two reads of one graph agree.
func (*GraphStore) NodeSource ¶ added in v2.99.0
func (g *GraphStore) NodeSource(ctx context.Context) (string, []any)
NodeSource and EdgeSource name the rows a read should see: a table name to put in a FROM clause, and the arguments it binds ahead of the query's own.
With no as-of on the context they return the bare table name, so the query the caller writes is byte-for-byte the query it was before this file existed — no subquery, no extra predicate, nothing for the planner to reconsider. Only a past read pays for the union of the live table and its history.
The caller appends its own alias and puts these arguments first, in the order the sources appear in the SQL text:
src, args := g.EdgeSource(ctx)
rows, err := db.Query(`SELECT id FROM `+src+` AS e WHERE edge_type = ?`,
append(args, "mentions")...)
Exported because pkg/cortexdb writes a good deal of its own SQL against graph_nodes and graph_edges, and a read there that ignored the as-of would be a read that silently answered a different question from the one beside it.
func (*GraphStore) NodeTypeCounts ¶ added in v2.85.0
NodeTypeCounts returns how many nodes carry each node_type.
Untyped nodes are counted under the empty string rather than dropped. A caller that sums these and compares against GetGraphStatistics should get the same number, and "there are 400 nodes nobody typed" is a finding in its own right — silently omitting them turns it into a discrepancy the caller has to explain.
func (*GraphStore) Now ¶ added in v2.99.0
func (g *GraphStore) Now() time.Time
Now reserves and returns an instant from this store's clock.
Every write this store makes afterwards is stamped strictly later, which is what makes "the state before that change" expressible without sleeping:
before := store.Now() store.UpsertNode(ctx, changed) store.GetNode(graph.AsOf(ctx, before), id) // the old content
func (*GraphStore) PageRank ¶
func (g *GraphStore) PageRank(ctx context.Context, iterations int, dampingFactor float64) ([]PageRankResult, error)
PageRank calculates PageRank scores for all nodes in the graph Optimized to load only topology (IDs and Edges) instead of full node objects.
func (*GraphStore) PredictEdges ¶
func (g *GraphStore) PredictEdges(ctx context.Context, nodeID string, topK int) ([]EdgePrediction, error)
PredictEdges predicts potential edges using various methods
func (*GraphStore) PropertyCounts ¶ added in v2.93.0
func (g *GraphStore) PropertyCounts(ctx context.Context, key string) (map[string]PropertyCount, error)
PropertyCounts groups every node and edge by one top-level property.
Records that do not carry the property at all are counted under the empty string, for the reason NodeTypeCounts gives about untyped nodes: "nothing says" is a finding, and dropping it turns a caller's sum into a discrepancy it has to go and explain. It is usually the most important number in the result — a breakdown over the 3% of a shelf that was stamped looks exactly like a breakdown over all of it.
func (*GraphStore) PropertyCountsOfKnowledge ¶ added in v2.110.0
func (g *GraphStore) PropertyCountsOfKnowledge(ctx context.Context, key string) (map[string]PropertyCount, error)
PropertyCountsOfKnowledge is PropertyCounts over the records that are claims about the world, with the store's own filing left out.
The difference is not cosmetic. A Decision node carries a contract of its own — somebody signed the decision, so it is stamped verified — and counting it under Verified says the brain has more established facts in it than it has. The chunks and their has_chunk edges carry no contract at all and land under Untagged, saying the opposite. A tally built to answer "how well established is what this brain knows" has to be asked only about the things the brain knows; the filing is counted by BookkeepingCount, as itself.
func (*GraphStore) Purge ¶ added in v2.99.0
func (g *GraphStore) Purge(ctx context.Context, before time.Time, dryRun bool) (*PurgeReport, error)
Purge physically removes history rows that closed before `before`.
The only hard delete in this file, and the reason the rest of it can be additive: history is storage that grows with every correction and every retraction, and an operator has to be able to get it back. It is a write.
"Closed" is retracted_at when the row was retracted and valid_to when it was superseded; every history row has one of them by construction. Both are past belief, and an operator reclaiming space wants both — a purge that left every superseded version behind would reclaim almost nothing on a graph that is corrected more often than it is deleted from.
Purge never touches a live table, so nothing a current read can see is at risk. It refuses a zero cutoff rather than reading it as "everything": the zero time is what an unset field looks like, and a caller that forgot to set one must not thereby erase the whole record.
func (*GraphStore) RecordsWithProperties ¶ added in v2.93.0
func (g *GraphStore) RecordsWithProperties(ctx context.Context, q PropertyRecordQuery) ([]PropertyRecord, error)
RecordsWithProperties lists the nodes and edges matching a property query.
Ordered by id within each table and nodes before edges, so two reads of one graph agree and a caller paging with Limit sees a stable sequence. Limit is applied to each table and then to the merged result: a cap that returned only nodes because they sorted first would hide every matching edge, which on a shelf whose assertions are mostly edges is the whole answer.
func (*GraphStore) RefreshRDFSInferences ¶ added in v2.16.0
func (g *GraphStore) RefreshRDFSInferences(ctx context.Context) (*RDFSInferenceRefreshResult, error)
RefreshRDFSInferences recomputes and persists inferred triples using an RDFS-lite ruleset.
func (*GraphStore) RefreshRDFSInferencesIncremental ¶ added in v2.18.0
func (g *GraphStore) RefreshRDFSInferencesIncremental(ctx context.Context, changedTriples []RDFTriple) (*RDFSInferenceRefreshResult, error)
RefreshRDFSInferencesIncremental recomputes inferred triples only for the neighborhood affected by the supplied changed explicit triples.
func (*GraphStore) RetractEdgeAt ¶ added in v2.99.0
RetractEdgeAt retracts one edge as of `at`. DeleteEdge is this, now.
func (*GraphStore) RetractNodeAt ¶ added in v2.99.0
RetractNodeAt retracts a node, and every edge touching it, as of `at`.
DeleteNode is this with `at` taken from the store's clock. The instant is a parameter because a retraction is a claim about when belief ended, and that is not always the moment somebody got round to running the delete: a fact discovered on Friday to have been wrong since Tuesday is retracted as of Tuesday, and every as-of read after Tuesday then agrees.
func (*GraphStore) RetractNodes ¶ added in v2.99.0
func (g *GraphStore) RetractNodes(ctx context.Context, nodeIDs []string) (nodes int, edges int, err error)
RetractNodes retracts many nodes in one transaction, reporting how many rows it found. Ids that match nothing are not an error — "not there" is not a failure to retract — so the count is what the caller should report.
func (*GraphStore) SPARQLMutates ¶ added in v2.91.0
func (g *GraphStore) SPARQLMutates(ctx context.Context, query string) bool
SPARQLMutates reports whether a query would change the graph.
It exists so authorization can tell a SPARQL read from a SPARQL write, and it is deliberately a thin wrapper over the executor's own parser rather than a second one. The alternative — a policy that recognises "INSERT" and "DELETE" by itself — has to agree with ExecuteSPARQL forever, and the failure when it stops agreeing is silent in the dangerous direction: an update the policy read as a query.
Without this the only safe classification is "every SPARQL call is a write", which costs a read-only key the whole query language, SELECT included.
A query that does not parse is reported as mutating. It is about to fail anyway, and the caller learns nothing from which error it gets.
func (*GraphStore) SaveRule ¶ added in v2.98.0
func (g *GraphStore) SaveRule(ctx context.Context, rule Rule, enabled bool) (*StoredRule, error)
SaveRule stores a rule under its id, replacing any rule already there.
func (*GraphStore) ShortestPath ¶
func (g *GraphStore) ShortestPath(ctx context.Context, fromID, toID string) (*PathResult, error)
ShortestPath finds the shortest path between two nodes using BFS
func (*GraphStore) SimilarityInGraph ¶
func (g *GraphStore) SimilarityInGraph(ctx context.Context, nodeID string, opts core.SearchOptions) ([]*HybridResult, error)
SimilarityInGraph finds nodes similar to a given node within the graph
func (*GraphStore) Subgraph ¶
func (g *GraphStore) Subgraph(ctx context.Context, nodeIDs []string) (*GraphResult, error)
Subgraph extracts a subgraph containing specified nodes and their connections
func (*GraphStore) SyncDeletedNodeIDs ¶ added in v2.14.1
func (g *GraphStore) SyncDeletedNodeIDs(_ context.Context, nodeIDs []string)
SyncDeletedNodeIDs removes committed graph-node deletions from the optional HNSW index.
func (*GraphStore) SyncUpsertedNodes ¶ added in v2.14.1
func (g *GraphStore) SyncUpsertedNodes(_ context.Context, nodes []*GraphNode)
SyncUpsertedNodes updates the optional graph HNSW index after nodes were committed through ExecuteBatchTx.
func (*GraphStore) UpsertEdge ¶
func (g *GraphStore) UpsertEdge(ctx context.Context, edge *GraphEdge) error
UpsertEdge inserts or updates an edge in the graph
func (*GraphStore) UpsertEdgesBatch ¶
func (g *GraphStore) UpsertEdgesBatch(ctx context.Context, edges []*GraphEdge) (*BatchResult, error)
UpsertEdgesBatch inserts or updates multiple edges in a single transaction
func (*GraphStore) UpsertNamespace ¶ added in v2.16.0
func (g *GraphStore) UpsertNamespace(ctx context.Context, ns Namespace) error
UpsertNamespace stores or replaces one namespace mapping.
func (*GraphStore) UpsertNode ¶
func (g *GraphStore) UpsertNode(ctx context.Context, node *GraphNode) error
UpsertNode inserts or updates a node in the graph
func (*GraphStore) UpsertNodesBatch ¶
func (g *GraphStore) UpsertNodesBatch(ctx context.Context, nodes []*GraphNode) (*BatchResult, error)
UpsertNodesBatch inserts or updates multiple nodes in a single transaction
func (*GraphStore) UpsertTriple ¶ added in v2.16.0
func (g *GraphStore) UpsertTriple(ctx context.Context, triple *RDFTriple) error
UpsertTriple writes one RDF triple/quad and mirrors it into the property graph tables.
func (*GraphStore) UpsertTriplesBatch ¶ added in v2.16.0
func (g *GraphStore) UpsertTriplesBatch(ctx context.Context, triples []*RDFTriple) (*BatchResult, error)
UpsertTriplesBatch writes multiple RDF triples/quads.
func (*GraphStore) ValidateSHACL ¶ added in v2.18.0
func (g *GraphStore) ValidateSHACL(ctx context.Context, shapeTriples []RDFTriple) (*SHACLReport, error)
ValidateSHACL runs SHACL validation against the graph store using the provided shapes.
type HNSWGraphIndex ¶
type HNSWGraphIndex struct {
// contains filtered or unexported fields
}
HNSWGraphIndex provides HNSW-accelerated graph searches
type HybridQuery ¶
type HybridQuery struct {
Vector []float32 `json:"vector,omitempty"`
StartNodeID string `json:"start_node_id,omitempty"`
CenterNodes []string `json:"center_nodes,omitempty"`
GraphFilter *GraphFilter `json:"graph_filter,omitempty"`
TopK int `json:"top_k"`
Threshold float64 `json:"threshold,omitempty"`
VectorThreshold float64 `json:"vector_threshold,omitempty"`
TotalThreshold float64 `json:"total_threshold,omitempty"`
VectorWeight float64 `json:"vector_weight"`
GraphWeight float64 `json:"graph_weight"`
Weights HybridWeights `json:"weights"`
}
HybridQuery represents a combined vector and graph query
type HybridResult ¶
type HybridResult struct {
Node *GraphNode `json:"node"`
VectorScore float64 `json:"vector_score"`
GraphScore float64 `json:"graph_score"`
CombinedScore float64 `json:"combined_score"`
TotalScore float64 `json:"total_score"`
Path []string `json:"path,omitempty"` // Path from start node
Distance int `json:"distance"` // Graph distance from start
}
HybridResult represents a result from hybrid search
type HybridWeights ¶
type HybridWeights struct {
VectorWeight float64 `json:"vector_weight"` // Weight for vector similarity
GraphWeight float64 `json:"graph_weight"` // Weight for graph proximity
EdgeWeight float64 `json:"edge_weight"` // Weight for edge strength
}
HybridWeights defines the weights for hybrid scoring
type Interval ¶ added in v2.99.0
Interval is a half-open span [From, To), matching how valid_from and valid_to are compared in SQL: a version that ends at the instant the next begins has no gap and no overlap.
A zero From is unbounded in the past and a zero To is unbounded in the future, which is what NULL means in those columns. The asymmetry is real — the same zero value means opposite things at the two ends — so the comparisons below never touch time.Time.Before directly.
func IntervalOf ¶ added in v2.99.0
IntervalOf builds an interval from a row's validity columns.
type IntervalRelation ¶ added in v2.99.0
type IntervalRelation struct {
// Subject is what both facts are about — the node both edges leave from.
// Two intervals with nothing in common are not worth relating.
Subject string `json:"subject"`
A string `json:"a"`
B string `json:"b"`
Relation AllenRelation `json:"relation"`
AFrom time.Time `json:"a_from,omitzero"`
ATo time.Time `json:"a_to,omitzero"`
BFrom time.Time `json:"b_from,omitzero"`
BTo time.Time `json:"b_to,omitzero"`
}
IntervalRelation is one named pair, as a diff or a snapshot reports it.
func RelateEdges ¶ added in v2.99.0
func RelateEdges(edges []*GraphEdge, maxPairs int) []IntervalRelation
RelateEdges names the temporal relation between every pair of edges that share a subject.
Bounded by maxPairs because the pair count is quadratic in the edges per subject: a node with two hundred facts about it yields twenty thousand pairs, which is a tool response nobody reads and a model cannot use.
type NodeChange ¶ added in v2.99.0
type NodeChange struct {
ID string `json:"id"`
Kind DiffKind `json:"kind"`
Before *NodeVersion `json:"before,omitempty"`
After *NodeVersion `json:"after,omitempty"`
}
NodeChange and EdgeChange carry both sides, so a reader sees what it said before as well as what it says now. Before is nil for an addition and After is nil for a retraction; a diff that reported only ids would send the caller back for two more reads per row.
type NodeLabel ¶ added in v2.86.0
type NodeLabel struct {
ID string `json:"id"`
NodeType string `json:"node_type"`
Content string `json:"content"`
}
NodeLabel is a node's identity together with what it is called.
type NodeLabelQuery ¶ added in v2.86.0
type NodeLabelQuery struct {
// IDPrefix keeps only nodes whose id starts with it. Node ids are
// namespaced by what wrote them, so this is how a caller asks for one
// writer's nodes without knowing how to recognise them from content.
// Matched literally: % and _ in the prefix are not wildcards.
IDPrefix string
// MinContentLength drops nodes whose label is shorter than this, counted
// in characters. 1 excludes the unlabelled.
MinContentLength int
// Limit caps the rows returned. 0 means no cap.
Limit int
}
NodeLabelQuery narrows NodeLabels. A zero query returns every node.
type NodeVersion ¶ added in v2.99.0
type NodeVersion struct {
ID string `json:"id"`
Content string `json:"content,omitempty"`
NodeType string `json:"node_type,omitempty"`
Properties string `json:"properties,omitempty"`
ValidFrom time.Time `json:"valid_from,omitzero"`
ValidTo time.Time `json:"valid_to,omitzero"`
}
NodeVersion is a node as it stood at one instant, without its vector.
The vector is left out on purpose: a diff of a thousand nodes would carry three megabytes of floats that answer nothing about what changed, and content is what changed.
func (NodeVersion) Interval ¶ added in v2.99.0
func (v NodeVersion) Interval() Interval
Interval is this version's validity, for Relate.
type PageRankResult ¶
PageRankResult represents the PageRank score for a node
type PathResult ¶
type PathResult struct {
Nodes []*GraphNode `json:"nodes"`
Edges []*GraphEdge `json:"edges"`
Distance int `json:"distance"`
Weight float64 `json:"weight"`
}
PathResult represents a path in the graph
type PropertyCount ¶ added in v2.93.0
PropertyCount is how many nodes and how many edges carry one value.
Kept apart rather than summed because the two are not interchangeable to a reader: an edge is an assertion about two things and a node is one thing, so "40 records" over a graph of 4 nodes and 36 edges describes a different graph than the reverse, and a caller that wants the total can add them.
type PropertyKeyUsage ¶ added in v2.94.0
type PropertyKeyUsage struct {
NodeType string `json:"node_type"`
Key string `json:"key"`
Records int `json:"records"`
Distinct int `json:"distinct_values"`
}
PropertyKeyUsage is one property key as it appears on the nodes of one type: how many of them carry it, and how many distinct values they carry.
Distinct is the field that earns the type. Coverage alone says a key is present; only distinctness separates a key that identifies a record from one that classifies it, which on a store of 4,000 nodes is the difference between `name` and `type` and is the only evidence data can offer about identity at all.
type PropertyRecord ¶ added in v2.93.0
type PropertyRecord struct {
ID string `json:"id"`
// Edge distinguishes the two without a caller having to guess from the
// shape of the id.
Edge bool `json:"edge"`
// Type is node_type or edge_type.
Type string `json:"type"`
// Content is a node's label. Edges have none — they are named by their
// type and their ends.
Content string `json:"content,omitempty"`
// From and To are an edge's ends, empty on a node. Ids rather than labels:
// resolving them costs a second query per row, and a caller that wants the
// labels has GetNodesBatch.
From string `json:"from,omitempty"`
To string `json:"to,omitempty"`
// Properties holds exactly the keys asked for. A key the record does not
// carry is absent rather than empty, so "nothing says" stays
// distinguishable from "says the empty string".
Properties map[string]string `json:"properties,omitempty"`
}
PropertyRecord is one node or edge, with the properties the caller asked for.
type PropertyRecordQuery ¶ added in v2.93.0
type PropertyRecordQuery struct {
// Where narrows to records carrying these properties. Keys are ANDed and
// the values within one key are ORed, which is the shape the questions
// actually take: "held or refused, from this import".
Where map[string][]string
// Fetch names the properties to return on each record. Empty returns the
// keys in Where, which is the common case and saves repeating them.
Fetch []string
// Limit caps the rows. 0 means no cap.
Limit int
}
PropertyRecordQuery narrows RecordsWithProperties. A zero query is refused rather than returning the whole graph: an unfiltered read of both tables is never what a caller of this API meant, and returning it makes the mistake look like it worked until the graph is large.
type PurgeReport ¶ added in v2.99.0
type PurgeReport struct {
Nodes int `json:"nodes"`
Edges int `json:"edges"`
Before time.Time `json:"before"`
DryRun bool `json:"dry_run,omitempty"`
}
PurgeReport is what Purge reclaimed.
type RDFFormat ¶ added in v2.16.0
type RDFFormat string
RDFFormat represents a supported RDF serialization format.
const ( // RDFFormatNTriples exports triples in N-Triples syntax. RDFFormatNTriples RDFFormat = "ntriples" // RDFFormatNQuads exports statements in N-Quads syntax when graph names are present. RDFFormatNQuads RDFFormat = "nquads" // RDFFormatTurtle exports statements in a Turtle-like syntax with prefixes when possible. RDFFormatTurtle RDFFormat = "turtle" // RDFFormatTriG exports quads in TriG syntax with graph blocks. RDFFormatTriG RDFFormat = "trig" )
type RDFSInferenceExplanation ¶ added in v2.16.0
type RDFSInferenceExplanation struct {
Triple RDFTriple `json:"triple"`
Explicit bool `json:"explicit"`
Rule string `json:"rule,omitempty"`
SupportTripleIDs []string `json:"support_triple_ids,omitempty"`
}
RDFSInferenceExplanation returns provenance information for one triple.
type RDFSInferenceMatchExplanation ¶ added in v2.18.0
type RDFSInferenceMatchExplanation struct {
Explanation RDFSInferenceExplanation `json:"explanation"`
Trace []RDFSInferenceTraceEntry `json:"trace,omitempty"`
}
RDFSInferenceMatchExplanation combines explanation and optional trace for one matched triple.
type RDFSInferenceRefreshResult ¶ added in v2.16.0
type RDFSInferenceRefreshResult struct {
ExplicitCount int `json:"explicit_count"`
InferredCount int `json:"inferred_count"`
Incremental bool `json:"incremental,omitempty"`
AffectedExplicitCount int `json:"affected_explicit_count,omitempty"`
RemovedInferredCount int `json:"removed_inferred_count,omitempty"`
}
RDFSInferenceRefreshResult summarizes a refresh of inferred triples.
type RDFSInferenceSummary ¶ added in v2.18.0
type RDFSInferenceSummary struct {
ExplicitCount int `json:"explicit_count"`
InferredCount int `json:"inferred_count"`
Rules map[string]int `json:"rules,omitempty"`
}
RDFSInferenceSummary provides persisted inference counts and rule breakdowns.
type RDFSInferenceTraceEntry ¶ added in v2.16.0
type RDFSInferenceTraceEntry struct {
TripleID string `json:"triple_id"`
ParentTripleID string `json:"parent_triple_id,omitempty"`
Depth int `json:"depth"`
Explanation RDFSInferenceExplanation `json:"explanation"`
Truncated bool `json:"truncated,omitempty"`
}
RDFSInferenceTraceEntry is one flattened node in an explanation trace.
type RDFTerm ¶ added in v2.16.0
type RDFTerm struct {
Kind string `json:"kind"`
Value string `json:"value"`
Datatype string `json:"datatype,omitempty"`
Language string `json:"language,omitempty"`
}
RDFTerm represents one RDF term.
func NewBlankNode ¶ added in v2.16.0
NewBlankNode creates a blank node term.
func NewLangLiteral ¶ added in v2.16.0
NewLangLiteral creates a language-tagged literal term.
func NewLiteral ¶ added in v2.16.0
NewLiteral creates a plain literal term.
func NewTypedLiteral ¶ added in v2.16.0
NewTypedLiteral creates a typed literal term.
type RDFTriple ¶ added in v2.16.0
type RDFTriple struct {
ID string `json:"id,omitempty"`
Subject RDFTerm `json:"subject"`
Predicate RDFTerm `json:"predicate"`
Object RDFTerm `json:"object"`
Graph *RDFTerm `json:"graph,omitempty"`
Inferred bool `json:"inferred,omitempty"`
Rule string `json:"rule,omitempty"`
SupportIDs []string `json:"support_ids,omitempty"`
// Provenance is carried onto the edge this triple becomes, so a triple
// written by a machine can say which machine, under whose authority, and
// on what grade. Nothing here is interpreted; it is the writer's statement
// about its own output, and keys that collide with the triple's own
// description are dropped rather than allowed to overwrite it.
//
// The RDF store had no such field, which meant every triple an import
// wrote was anonymous: the row it came from, the plan that was signed to
// read it, and the operator who signed it were all recoverable from the
// ledger and from nothing on the fact itself.
Provenance map[string]string `json:"provenance,omitempty"`
}
RDFTriple represents one RDF triple or quad when Graph is set.
type ReadOptions ¶ added in v2.99.0
type ReadOptions struct {
// AsOf reads the graph as it stood at this instant. The zero time means
// now, which is what every caller before this field got and still gets.
AsOf time.Time
}
ReadOptions is how much of the past a read is allowed to see.
Carried on the context rather than passed as an argument, which is the unusual choice and a deliberate one. The alternative is a parameter on every read, and the read surface here is not flat: Neighbors calls GetEdges, which calls nothing; ShortestPath calls GetEdges and getEdgeByID; ExpandGraph in pkg/cortexdb calls Neighbors; HybridSearch calls its own scan. Threading a parameter means changing the signature of every one of them — breaking every caller in and outside this module — or shipping an As-Of twin of each and letting the two drift. An as-of read is also not really an argument to one query: it is the epoch the whole traversal happens in, and a traversal that read some hops at one instant and some at another would produce a graph that never existed.
The risk of an ambient setting is that it leaks into a write. That is closed rather than documented away: every write path calls errIfAsOf and refuses.
func ReadOptionsFrom ¶ added in v2.99.0
func ReadOptionsFrom(ctx context.Context) ReadOptions
ReadOptionsFrom reads back what WithReadOptions put on the context. The zero value — read now — is returned for a context that carries nothing.
func (ReadOptions) IsAsOf ¶ added in v2.99.0
func (r ReadOptions) IsAsOf() bool
AsOf reports whether these options ask for a past read.
type Rule ¶ added in v2.98.0
type Rule struct {
// ID is the stable identity written into every edge this rule derives, and
// the key it persists under. Required.
ID string `json:"id"`
// Name is a human label. Optional; it never participates in matching.
Name string `json:"name,omitempty"`
// When are the premises, matched in order. Each one is a graph edge
// pattern; a variable bound by an earlier premise constrains the later
// ones.
When []Atom `json:"when"`
// Then is the conclusion. Every variable in it must be bound by some
// premise — see Validate, which is what stops a rule deriving edges
// between nodes it never looked at.
Then Atom `json:"then"`
// Confidence multiplies into every derived edge's confidence. Zero means
// 1.0, so a rule that says nothing about confidence does not silently
// erase the premises'.
Confidence float64 `json:"confidence,omitempty"`
// Note is free text carried alongside the rule for whoever reads it later.
Note string `json:"note,omitempty"`
// Weight overrides the derived edge weight. Zero means the mean of the
// premise weights, which for a two-premise rule is the average the
// original two-hop inference wrote.
Weight float64 `json:"weight,omitempty"`
// Metadata is written onto every derived edge, except for the provenance
// keys the engine owns — those cannot be overridden, because an edge whose
// rule_id says something other than the rule that derived it is an edge
// that lies to inference_explain.
Metadata map[string]string `json:"metadata,omitempty"`
}
Rule is a Horn clause over graph edges: derive Then whenever every atom in When can be matched with one consistent set of variable bindings.
func ParseRule ¶ added in v2.98.0
ParseRule parses the textual form and gives the result an ID, which is the common case: a caller with a rule to save has both.
func ParseRuleText ¶ added in v2.98.0
ParseRuleText parses the textual form into a Rule with When and Then filled in. ID, Name, Confidence and Metadata are the caller's to set: they are bookkeeping about the rule, not part of the logic it states.
type RuleApplyResult ¶ added in v2.98.0
type RuleApplyResult struct {
// Iterations is how many chaining rounds actually ran.
Iterations int `json:"iterations"`
// CandidateEdges is how many stored edges took part as facts.
CandidateEdges int `json:"candidate_edges"`
// CreatedEdgeIDs are the edges this run wrote, sorted. On a dry run they
// are the edges it would have written.
CreatedEdgeIDs []string `json:"created_edge_ids,omitempty"`
// UnchangedEdgeIDs are edges this rule set re-derived that were already
// stored by the same rule. Reported rather than rewritten, which is what
// makes a second run of the same rules a no-op.
UnchangedEdgeIDs []string `json:"unchanged_edge_ids,omitempty"`
// Edges are the derived edges in CreatedEdgeIDs order, with the provenance
// they carry.
Edges []*GraphEdge `json:"edges,omitempty"`
// UnresolvedTerms are literal terms in the rules that match no stored node,
// so the rules mentioning them could never fire. Reported because a rule
// that silently matches nothing looks exactly like a rule that is simply
// not true of this graph.
UnresolvedTerms []string `json:"unresolved_terms,omitempty"`
// CapHit and CapReason say the run stopped at a cap rather than at a
// fixpoint. When they are set nothing was written and ApplyRules returned
// ErrRuleCapExceeded.
CapHit bool `json:"cap_hit,omitempty"`
CapReason string `json:"cap_reason,omitempty"`
// DryRun echoes the option, so a caller reading only the result can tell
// whether the edges it lists are in the store.
DryRun bool `json:"dry_run,omitempty"`
}
RuleApplyResult reports what one forward-chaining run did.
type RuleEdgeExplanation ¶ added in v2.98.0
type RuleEdgeExplanation struct {
EdgeID string `json:"edge_id"`
EdgeType string `json:"edge_type,omitempty"`
FromNodeID string `json:"from_node_id,omitempty"`
ToNodeID string `json:"to_node_id,omitempty"`
Inferred bool `json:"inferred"`
Provenance string `json:"provenance,omitempty"`
RuleID string `json:"rule_id,omitempty"`
RuleText string `json:"rule_text,omitempty"`
Confidence float64 `json:"confidence,omitempty"`
// SupportEdgeIDs are the exact premise edges, in the order of the rule's
// premises.
SupportEdgeIDs []string `json:"support_edge_ids,omitempty"`
// Missing marks a premise edge that is no longer in the graph — somebody
// deleted the evidence without retracting the conclusion.
Missing bool `json:"missing,omitempty"`
}
RuleEdgeExplanation says why one edge is in the graph.
An explicit edge explains itself: Inferred is false and it names no support. A derived edge names the rule that derived it — including the rule text, which is stored on the edge rather than looked up, so an edge stays explicable after its rule is deleted or edited — and the exact premise edges under it.
It is deliberately one level deep. The chain is returned separately, by ExplainEdgeTrace, as a flat list: a self-referential struct cannot be given a JSON schema, so a nested explanation could never have crossed the MCP boundary most callers reach this through.
type RuleEdgeTraceEntry ¶ added in v2.98.0
type RuleEdgeTraceEntry struct {
EdgeID string `json:"edge_id"`
ParentEdgeID string `json:"parent_edge_id,omitempty"`
Depth int `json:"depth"`
Explanation RuleEdgeExplanation `json:"explanation"`
// Truncated marks an inferred edge whose own premises were not followed,
// because the depth ran out or because the chain looped. Without it a leaf
// of a truncated trace reads as an explicit edge.
Truncated bool `json:"truncated,omitempty"`
}
RuleEdgeTraceEntry is one node of a flattened derivation, in preorder: the edge asked about at depth 0, then its premises, then theirs.
type RuleOptions ¶ added in v2.98.0
type RuleOptions struct {
// DocumentID scopes which edges may take part and is stamped onto what is
// derived. Empty means the whole graph, and derived edges inherit a
// document only when every premise agrees on one.
DocumentID string
// MaxIterations caps the chaining rounds. Zero means DefaultRuleMaxIterations.
MaxIterations int
// MaxDerived caps how many edges one run may derive. Zero means
// DefaultRuleMaxDerived.
MaxDerived int
// DryRun computes the derivation and writes nothing. The result carries the
// edges it would have written.
DryRun bool
// Validate, when set, is given the derived edges before they are written
// and can refuse them. It exists because the ontology that decides whether
// a relation is legal lives a layer up, and derived edges have to pass the
// same gate hand-written ones do.
Validate func(ctx context.Context, edges []*GraphEdge) error
}
RuleOptions configures one forward-chaining run.
type RuleParseError ¶ added in v2.98.0
type RuleParseError struct {
// Offset is a 0-based byte offset into the source text.
Offset int
// Message says what was expected there.
Message string
// Source is the text that failed to parse.
Source string
}
RuleParseError names where parsing stopped. A rule is usually typed by hand and usually wrong on the first try, so "expected ')'" without a position is most of an error message missing.
func (*RuleParseError) Error ¶ added in v2.98.0
func (e *RuleParseError) Error() string
type SHACLReport ¶ added in v2.18.0
type SHACLReport struct {
Conforms bool `json:"conforms"`
Results []SHACLValidationResult `json:"results,omitempty"`
}
SHACLReport contains the outcome of SHACL validation.
type SHACLValidationResult ¶ added in v2.18.0
type SHACLValidationResult struct {
FocusNode RDFTerm `json:"focus_node"`
Path RDFTerm `json:"path"`
Value RDFTerm `json:"value,omitempty"`
Message string `json:"message"`
Severity string `json:"severity"`
Source RDFTerm `json:"source_shape"`
}
SHACLValidationResult represents a single constraint violation.
type SPARQLResult ¶ added in v2.16.0
type SPARQLResult struct {
QueryType string `json:"query_type"`
Vars []string `json:"vars,omitempty"`
Bindings []map[string]RDFTerm `json:"bindings,omitempty"`
Triples []RDFTriple `json:"triples,omitempty"`
Boolean bool `json:"boolean,omitempty"`
Count int `json:"count"`
}
SPARQLResult contains the result of executing a SPARQL query.
type SimpleHNSW ¶
type SimpleHNSW struct {
// contains filtered or unexported fields
}
SimpleHNSW implements a simplified HNSW-like index for vector search
func NewSimpleHNSW ¶
func NewSimpleHNSW(dimensions int, maxConns int) *SimpleHNSW
NewSimpleHNSW creates a new simplified HNSW index
func (*SimpleHNSW) Add ¶
func (h *SimpleHNSW) Add(id string, vector []float32) error
Add inserts a vector into the HNSW index
func (*SimpleHNSW) Remove ¶
func (h *SimpleHNSW) Remove(nodeID string)
Remove removes a node from the index
func (*SimpleHNSW) Search ¶
func (h *SimpleHNSW) Search(query []float32, k int) []searchCandidate
Search performs HNSW search
type StoredRule ¶ added in v2.98.0
type StoredRule struct {
Rule
// Text is the rule rendered into the textual form, stored alongside the
// structured body so a human reading the table sees the rule.
Text string `json:"text"`
Enabled bool `json:"enabled"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
StoredRule is a rule as persisted, with the bookkeeping the store adds.
type TraversalOptions ¶
type TraversalOptions struct {
MaxDepth int `json:"max_depth"`
EdgeTypes []string `json:"edge_types,omitempty"`
NodeTypes []string `json:"node_types,omitempty"`
Direction string `json:"direction"` // "out", "in", "both"
Limit int `json:"limit"`
}
TraversalOptions defines options for graph traversal
type TriplePattern ¶ added in v2.16.0
type TriplePattern struct {
Subject *RDFTerm `json:"subject,omitempty"`
Predicate *RDFTerm `json:"predicate,omitempty"`
Object *RDFTerm `json:"object,omitempty"`
Graph *RDFTerm `json:"graph,omitempty"`
Inferred *bool `json:"inferred,omitempty"`
Limit int `json:"limit,omitempty"`
}
TriplePattern filters triple lookup operations. Nil fields behave as wildcards.
Source Files
¶
- graph.go
- graph_algorithms.go
- graph_batch.go
- graph_export.go
- graph_hnsw.go
- graph_hybrid.go
- graph_traversal.go
- graph_tx.go
- graph_vocabulary.go
- index_sync.go
- pgvector.go
- rdf.go
- rdf_external.go
- rdfs.go
- rules.go
- rules_engine.go
- rules_explain.go
- rules_parse.go
- rules_store.go
- shacl.go
- sparql.go
- sparql_mutates.go
- temporal.go
- temporal_allen.go
- temporal_diff.go