feat(graph): add update_node and keyword_search methods#670
feat(graph): add update_node and keyword_search methods#670Charitablebusinessronin wants to merge 1 commit into
Conversation
## update_node Adds to GraphDB — the counterpart to . Enables in-place property updates on existing nodes without delete+recreate. This unblocks SUPERSEDES-style versioning where a prior node is marked without deleting it: Returns if the node was not found (no error), if updated. Persists to storage if the feature is enabled. Closes ruvnet#666 ## keyword_search Adds to GraphDB — wires the existing (bm25.rs) into the graph API. Returns top-k node IDs by BM25 score over a text property for nodes with the given label. This is the keyword arm of hybrid search — pair with vector ANN for reciprocal rank fusion. Builds a transient index on each call (suitable for small-to-medium graphs or one-shot queries). Closes ruvnet#667 ## Tests 4 new tests, all passing: - test_update_node — marks a node deprecated, verifies properties changed - test_update_node_not_found — returns Ok(false) for missing node - test_keyword_search — ranks relevant docs first, pasta doc doesn't lead - test_keyword_search_empty_label — empty label returns empty results Full suite: 21/21 pass (0.11s) ## Context Filed by Allura (github.com/Allura-Ecosystem/Allura_Memory) during the RuVector graph cutover (AD-49). Allura uses the graph adapter for governed memory with SUPERSEDES versioning and hybrid search.
|
Thanks for tackling #666/#667 — the direction is right and the BM25 implementation in Requesting changes before merge on two correctness issues in
Smaller/non-blocking: Happy to re-review once the index-refresh + atomicity are addressed. |
Summary
Adds two methods to
GraphDBthat unblock SUPERSEDES-style versioning and hybrid search for downstream consumers.update_node(id, f)— closes #666The counterpart to
create_node. Enables in-place property updates on existing nodes without delete+recreate. This unblocks SUPERSEDES-style versioning where a prior node is markeddeprecatedwithout deleting it:Ok(false)if the node was not found (no error)Ok(true)if updated successfullystoragefeature is enabledNodealready hadset_property()— this exposes it at the graph levelkeyword_search(label, text_field, query, k)— closes #667Wires the existing
Bm25Index(bm25.rs) into theGraphDBAPI. Returns top-k node IDs by BM25 score over a text property for nodes with the given label. This is the keyword arm of hybrid search — pair with vector ANN for reciprocal rank fusion.Bm25Indexon each call (suitable for small-to-medium graphs)Tests
4 new tests, all passing:
test_update_nodetest_update_node_not_foundtest_keyword_searchtest_keyword_search_empty_labelFull suite: 21/21 pass (0.11s)
Build
Context
Filed by Allura during the RuVector graph cutover (AD-49). Allura uses the graph adapter for governed memory with SUPERSEDES versioning and hybrid search. Issues #666 and #667 were filed to request these capabilities.
What's NOT in this PR
keyword_searchrebuilds on every call. A cached variant behind a feature flag is a follow-up if needed.update_node— the current implementation re-inserts intoself.nodesbut doesn't refreshlabel_index/property_index. For property lookups this is fine (the old entry returns the same node ID). A production-gradeupdate_nodeshould add anupdate_nodemethod to the index structs — this PR keeps it minimal and correct.License
RuVector is MIT. This contribution is offered under the same license.