Skip to content

query: single generic term exact-matching a short leaf label hijacks seed selection in multi-term queries #1602

Description

@fkhawajagh

Summary

In a multi-term query, a single generic term that exactly equals a short, unrelated leaf node's label receives the _EXACT_MATCH_BONUS (1000×IDF) and outscores every genuinely relevant node by ~10×. _pick_seeds (gap_ratio 0.2) then drops all other candidates, so the traversal starts from one irrelevant leaf and returns a tiny dead-end subgraph.

Observed on graphifyy 0.8.49.

Repro (real graph, Phoenix/Elixir codebase, ~5,400 nodes)

Query:

graphify query "dashboard home page LiveView content KPI cards alerts today grid"

The graph contains a rich cluster for the dashboard feature (IrisWeb.DashboardLive, kpi_card(), alert_row(), plus design docs whose labels match 3 of the query terms). Expected seeds somewhere in that cluster.

Actual _score_nodes output (top of the ranking):

6037.89  home()                          <- "home" == bare label -> exact tier
 680.74  grid_view()                     <- "grid" prefix tier
 621.57  Home / Today Dashboard (Iris)   <- 3 substring hits
 616.01  Home Today Mock

_pick_seeds keeps only home() because every other node is below 20% of the top score. home() is a 2-neighbor leaf (a controller action), so BFS depth 2 returns 3 nodes and the answer collapses:

Traversal: BFS depth=2 | Start: ['home()'] | 3 nodes found

The failure generalizes: any generic English word in a concept query that happens to equal (or prefix) a short function name hijacks the seed. Same graph, "dashboard liveview kpi alerts today grid" seeds at grid_view() / gridlines() for the same reason, while "dashboard KPI alerts" (no colliding generic words) seeds correctly.

Why this feels like a scorer bug rather than user error

The exact-match tier is clearly right for identifier queries (graphify query "FooBarService"). But in a 10-term query, an exact hit on one term says much less than substring hits on three terms. The current scoring has no notion of term coverage, so one lucky collision dominates, and the aggressive seed gap then removes all diversity.

Possible directions

  • Weight the exact/prefix bonuses by the fraction of query terms the node matches, so a 1-of-10 exact hit can't bury a 3-of-10 multi-term match.
  • Or relax _pick_seeds when the top seed's score comes from a single term of a many-term query — keep at least one seed from the best multi-term-coverage node.
  • Or treat very short labels (home, grid) as low-information exact matches, e.g. dampen the exact bonus by label-token IDF.

Happy to provide more score traces if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions