feat(8.0): related({ node }) — one-call both-direction incident edges
related({ from }) / related({ to }) each return one direction; related({ node })
unions both (every edge where the node is source OR target), deduped, in a single
O(degree) call — the indexed equivalent of merging two related() calls by hand.
The 'all edges on a noun' query the graph-viz path needs.
- RelatedParams.node: mutually exclusive with from/to (throws if combined);
composes with type/subtype/visibility filters; natural-key ids resolved.
- Implemented as a parallel out-edge (sourceId) + in-edge (targetId) fetch through
the O(degree) graph-index fast paths, merged + deduped by id (a self-loop appears
once), sorted for a stable page. Full incidence is the intended O(degree) cost;
deep offset paging of a very-high-degree node is best-effort (use the native
edgesForNode / a graph cursor for exhaustive paging).
- db.related() parity: node resolved + honored in relationMatchesParams (matches an
edge incident in either direction) for the historical/overlay paths.
Test: related-node-bidirectional.test.ts — both directions, equals from∪to, self-loop
dedupe, type-filter composition, default-hides-internal, node+from/to throws.
This commit is contained in:
parent
a3d6fdb8b3
commit
d4de48d004
4 changed files with 161 additions and 19 deletions
|
|
@ -460,7 +460,8 @@ export class Db<T = any> {
|
|||
const params: RelatedParams = {
|
||||
...rawParams,
|
||||
...(rawParams.from !== undefined && { from: resolveEntityId(rawParams.from) }),
|
||||
...(rawParams.to !== undefined && { to: resolveEntityId(rawParams.to) })
|
||||
...(rawParams.to !== undefined && { to: resolveEntityId(rawParams.to) }),
|
||||
...(rawParams.node !== undefined && { node: resolveEntityId(rawParams.node) })
|
||||
}
|
||||
const historical = this.isHistorical()
|
||||
|
||||
|
|
@ -1024,6 +1025,10 @@ function sortResultsBy<T>(results: Result<T>[], orderBy: string, order: 'asc' |
|
|||
* `to` → targetId, type/subtype set membership, service equality).
|
||||
*/
|
||||
function relationMatchesParams<T>(relation: Relation<T>, params: RelatedParams): boolean {
|
||||
// `node` matches an edge incident in EITHER direction (the both-direction shorthand).
|
||||
if (params.node !== undefined && relation.from !== params.node && relation.to !== params.node) {
|
||||
return false
|
||||
}
|
||||
if (params.from !== undefined && relation.from !== params.from) return false
|
||||
if (params.to !== undefined && relation.to !== params.to) return false
|
||||
if (params.type !== undefined) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue