diff --git a/lance_csr/README.md b/lance_csr/README.md index 6ce785c..283386c 100644 --- a/lance_csr/README.md +++ b/lance_csr/README.md @@ -35,4 +35,4 @@ From the repository root, `./run_benchmarks.sh lance_csr` runs both modes with t LANCE_CSR_MODE=memory uv run --frozen pytest benchmark_query.py --benchmark-min-rounds=5 --benchmark-disable-gc ``` -The runner doesn't pass lance-csr's `timeout` argument, so `QUERY_TIMEOUT_SECONDS` doesn't apply and queries run without a limit. The shared lance-graph query module uses the deprecated `with_node_label` and `with_relationship` builder methods, so each run prints deprecation warnings. +The runner doesn't pass lance-csr's `timeout` argument, so `QUERY_TIMEOUT_SECONDS` doesn't apply and queries run without a limit. `query.py` replaces the shared module's `build_config()`, which uses lance-graph's builder methods, with one that uses lance-csr's `node_table` and `rel_table`. It reads each relationship's endpoint node tables from its dataset name (`person_likes_post` goes from `Person` to `Post`). diff --git a/lance_csr/query.py b/lance_csr/query.py index 93f7247..813e521 100644 --- a/lance_csr/query.py +++ b/lance_csr/query.py @@ -1,7 +1,8 @@ """Run lance_graph/query.py's 30 queries on lance-csr. -The queries, graph mapping and data (lance_graph/graph_lance) are shared with lance-graph, so both -engines answer identical Cypher over identical Lance datasets. +The queries and data (lance_graph/graph_lance) are shared with lance-graph, so both engines answer +identical Cypher over identical Lance datasets. The graph mapping is the same, but built with +lance-csr's node_table and rel_table, which also name each relationship's endpoint node tables. LANCE_CSR_MODE picks how the datasets are read; both use CSR traversal (use_csr=True): - memory (default): every table loaded into memory as Arrow, as lance-graph's benchmark does @@ -29,6 +30,22 @@ _spec.loader.exec_module(q) q.CypherEngine = functools.partial(lance_csr.CypherEngine, use_csr=True) + + +def build_config() -> lance_csr.GraphConfig: + # lance-csr's rel_table names the node tables at both ends; read them from the dataset names, + # such as person_likes_post for Person to Post. + labels = {label.lower(): label for label in q.NODE_LABELS} + builder = lance_csr.GraphConfig.builder() + for label in q.NODE_LABELS: + builder = builder.node_table(label, "id") + for rel_type, dataset_name in q.REL_DATASETS.items(): + parts = dataset_name.split("_") + builder = builder.rel_table(rel_type, labels[parts[0]], labels[parts[-1]], "src", "dst") + return builder.build() + + +q.build_config = build_config if MODE == "lazy": def load_datasets(root: Path) -> dict[str, lance.LanceDataset]: names = {label: label for label in q.NODE_LABELS} | q.REL_DATASETS