Skip to content

Bucket global search results by type instead of one merged, unranked list - #1344

Merged
tomchop merged 1 commit into
mainfrom
feat/global-search-sections
Aug 13, 2026
Merged

Bucket global search results by type instead of one merged, unranked list#1344
tomchop merged 1 commit into
mainfrom
feat/global-search-sections

Conversation

@tomchop

@tomchop tomchop commented Aug 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Global search matched name/value/tags with the same case-insensitive substring LIKE across every object type in one shared, unranked page. A hash observable containing the search term as a substring (e.g. fed inside a sha256) could drown out real entity/indicator/dfiq name matches.
  • Adds ArangoYetiConnector.grouped_search(): one AQL query against the existing all_objects_view that buckets results per type (entity, indicator, dfiq, observable), each with its own independent count/total. High-volume matches in one type can no longer push another type's matches out of the response.
  • Rewrites POST /search/ to use this instead of the generic base-class filter() path (confirmed nothing else in the codebase used that path).

Test plan

  • tests/apiv2/search.py rewritten for the new contract: per-type bucketing, tag/dfiq_tags substring matching, count_per_type limiting, RBAC/ACL filtering, and a dedicated regression test reproducing the reported bug (12 matching hashes can't crowd out an entity match).
  • Full unittest suite (schemas, apiv2, core_tests) run locally — no regressions (10 pre-existing failures are unrelated /opt/yeti/... permission issues in this sandbox, not caused by this change).
  • ruff check/format --check and ty check clean on touched files.
  • Manually verified end-to-end against seeded data reproducing the exact reported scenario (a "Federated Exfiltration" DFIQ scenario + entity + 12 sha256 hashes all containing "fed") — both real matches surface correctly.

Companion frontend PR (sectioned GlobalSearch.vue UI) to follow.

…list

Global search matched name/value/tags with the same case-insensitive
substring LIKE across every object type in one shared page, so a hash
observable containing the search term as a substring (e.g. "fed" inside a
sha256) could crowd out real entity/indicator/dfiq name matches. Rewrites
/search/ to run one AQL query that buckets results per type (entity,
indicator, dfiq, observable), each with its own independent count/total,
so high-volume matches in one type can never push another type's matches
out of the response.
@tomchop
tomchop merged commit 55757a3 into main Aug 13, 2026
5 checks passed
@tomchop
tomchop deleted the feat/global-search-sections branch August 13, 2026 12:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant