mirror of
https://github.com/trustgraph-ai/trustgraph.git
synced 2026-07-23 04:01:02 +02:00
Cassandra index design in the tech spec
This commit is contained in:
parent
30699edf08
commit
c03d2eed30
1 changed files with 79 additions and 28 deletions
|
|
@ -228,10 +228,15 @@ Following SPARQL conventions for backward compatibility:
|
||||||
|
|
||||||
- **`g` omitted / None**: Query the default graph only
|
- **`g` omitted / None**: Query the default graph only
|
||||||
- **`g` = specific IRI**: Query that named graph only
|
- **`g` = specific IRI**: Query that named graph only
|
||||||
- **`g` = wildcard / `*`**: Query across all graphs
|
- **`g` = wildcard / `*`**: Query across all graphs (equivalent to SPARQL
|
||||||
|
`GRAPH ?g { ... }`)
|
||||||
|
|
||||||
This keeps simple queries simple and makes named graph queries opt-in.
|
This keeps simple queries simple and makes named graph queries opt-in.
|
||||||
|
|
||||||
|
Cross-graph queries (g=wildcard) are fully supported. The Cassandra schema
|
||||||
|
includes dedicated tables (SPOG, POSG, OSPG) where g is a clustering column
|
||||||
|
rather than a partition key, enabling efficient queries across all graphs.
|
||||||
|
|
||||||
#### Temporal Queries
|
#### Temporal Queries
|
||||||
|
|
||||||
**Find all facts discovered after a given date:**
|
**Find all facts discovered after a given date:**
|
||||||
|
|
@ -388,12 +393,78 @@ will proceed in phases:
|
||||||
Cassandra requires multiple tables to support different query access patterns
|
Cassandra requires multiple tables to support different query access patterns
|
||||||
(each table efficiently queries by its partition key + clustering columns).
|
(each table efficiently queries by its partition key + clustering columns).
|
||||||
|
|
||||||
**Challenge: Quads**
|
##### Query Patterns
|
||||||
|
|
||||||
For triples, typical indexes are SPO, POS, OSP (partition by first, cluster by
|
With quads (g, s, p, o), each position can be specified or wildcard, giving
|
||||||
rest). For quads, the graph dimension adds: SPOG, POSG, OSPG, GSPO, etc.
|
16 possible query patterns:
|
||||||
|
|
||||||
**Challenge: Quoted Triples**
|
| # | g | s | p | o | Description |
|
||||||
|
|---|---|---|---|---|-------------|
|
||||||
|
| 1 | ? | ? | ? | ? | All quads |
|
||||||
|
| 2 | ? | ? | ? | o | By object |
|
||||||
|
| 3 | ? | ? | p | ? | By predicate |
|
||||||
|
| 4 | ? | ? | p | o | By predicate + object |
|
||||||
|
| 5 | ? | s | ? | ? | By subject |
|
||||||
|
| 6 | ? | s | ? | o | By subject + object |
|
||||||
|
| 7 | ? | s | p | ? | By subject + predicate |
|
||||||
|
| 8 | ? | s | p | o | Full triple (which graphs?) |
|
||||||
|
| 9 | g | ? | ? | ? | By graph |
|
||||||
|
| 10 | g | ? | ? | o | By graph + object |
|
||||||
|
| 11 | g | ? | p | ? | By graph + predicate |
|
||||||
|
| 12 | g | ? | p | o | By graph + predicate + object |
|
||||||
|
| 13 | g | s | ? | ? | By graph + subject |
|
||||||
|
| 14 | g | s | ? | o | By graph + subject + object |
|
||||||
|
| 15 | g | s | p | ? | By graph + subject + predicate |
|
||||||
|
| 16 | g | s | p | o | Exact quad |
|
||||||
|
|
||||||
|
##### Table Design
|
||||||
|
|
||||||
|
Cassandra constraint: You can only efficiently query by partition key, then
|
||||||
|
filter on clustering columns left-to-right. For g-wildcard queries, g must be
|
||||||
|
a clustering column. For g-specified queries, g in the partition key is more
|
||||||
|
efficient.
|
||||||
|
|
||||||
|
**Two table families needed:**
|
||||||
|
|
||||||
|
**Family A: g-wildcard queries** (g in clustering columns)
|
||||||
|
|
||||||
|
| Table | Partition | Clustering | Supports patterns |
|
||||||
|
|-------|-----------|------------|-------------------|
|
||||||
|
| SPOG | (user, collection, s) | p, o, g | 5, 7, 8 |
|
||||||
|
| POSG | (user, collection, p) | o, s, g | 3, 4 |
|
||||||
|
| OSPG | (user, collection, o) | s, p, g | 2, 6 |
|
||||||
|
|
||||||
|
**Family B: g-specified queries** (g in partition key)
|
||||||
|
|
||||||
|
| Table | Partition | Clustering | Supports patterns |
|
||||||
|
|-------|-----------|------------|-------------------|
|
||||||
|
| GSPO | (user, collection, g, s) | p, o | 9, 13, 15, 16 |
|
||||||
|
| GPOS | (user, collection, g, p) | o, s | 11, 12 |
|
||||||
|
| GOSP | (user, collection, g, o) | s, p | 10, 14 |
|
||||||
|
|
||||||
|
**Collection table** (for iteration and bulk deletion)
|
||||||
|
|
||||||
|
| Table | Partition | Clustering | Purpose |
|
||||||
|
|-------|-----------|------------|---------|
|
||||||
|
| COLL | (user, collection) | g, s, p, o | Enumerate all quads in collection |
|
||||||
|
|
||||||
|
##### Write and Delete Paths
|
||||||
|
|
||||||
|
**Write path**: Insert into all 7 tables.
|
||||||
|
|
||||||
|
**Delete collection path**:
|
||||||
|
1. Iterate COLL table for `(user, collection)`
|
||||||
|
2. For each quad, delete from all 6 query tables
|
||||||
|
3. Delete from COLL table (or range delete)
|
||||||
|
|
||||||
|
**Delete single quad path**: Delete from all 7 tables directly.
|
||||||
|
|
||||||
|
##### Storage Cost
|
||||||
|
|
||||||
|
Each quad is stored 7 times. This is the cost of flexible querying combined
|
||||||
|
with efficient collection deletion.
|
||||||
|
|
||||||
|
##### Quoted Triples in Storage
|
||||||
|
|
||||||
Subject or object can be a triple itself. Options:
|
Subject or object can be a triple itself. Options:
|
||||||
|
|
||||||
|
|
@ -425,29 +496,9 @@ Metadata table:
|
||||||
- Pro: Clean separation, can index triple IDs
|
- Pro: Clean separation, can index triple IDs
|
||||||
- Con: Requires computing/managing triple identity, two-phase lookups
|
- Con: Requires computing/managing triple identity, two-phase lookups
|
||||||
|
|
||||||
**Option C: Hybrid**
|
**Recommendation**: Start with Option A (serialized strings) for simplicity.
|
||||||
- Store quads normally with serialized quoted triple strings for simple cases
|
Option B may be needed if advanced query patterns over quoted triple
|
||||||
- Maintain a separate triple ID lookup for advanced queries
|
components are required.
|
||||||
- Pro: Flexibility
|
|
||||||
- Con: Complexity
|
|
||||||
|
|
||||||
**Recommendation**: TBD after prototyping. Option A is simplest for initial
|
|
||||||
implementation; Option B may be needed for advanced query patterns.
|
|
||||||
|
|
||||||
#### Indexing Strategy
|
|
||||||
|
|
||||||
Indexes must support the defined query patterns:
|
|
||||||
|
|
||||||
| Query Type | Access Pattern | Index Needed |
|
|
||||||
|------------|----------------|--------------|
|
|
||||||
| Facts by date | P=discoveredOn, O>date | POG (predicate, object, graph) |
|
|
||||||
| Facts by source | P=supportedBy, O=source | POG |
|
|
||||||
| Facts by asserter | P=assertedBy, O=person | POG |
|
|
||||||
| Metadata for a fact | S=quotedTriple | SPO/SPOG |
|
|
||||||
| All facts in graph | G=graphIRI | GSPO |
|
|
||||||
|
|
||||||
For temporal range queries (dates), Cassandra clustering column ordering
|
|
||||||
enables efficient scans when date is a clustering column.
|
|
||||||
|
|
||||||
2. **Phase 2+: Other Backends**
|
2. **Phase 2+: Other Backends**
|
||||||
- Neo4j and other stores implemented in subsequent stages
|
- Neo4j and other stores implemented in subsequent stages
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue