Zoekt: Use TotalLineMatchCount / TotalFileMatchCount for accurate result counts

Background

Gitlab::Search::Zoekt::Response currently reads FileMatchCount and LineMatchCount from the coordinating node response for display counts (e.g., "5,000+ results"). These fields reflect the trimmed result set — the count of files and line matches actually included in the JSON response after post-sort trimming.

The coordinating node also returns TotalFileMatchCount and TotalLineMatchCount, which are raw Zoekt engine stats representing a lower-bound estimate of total matches across all downstream nodes (independent of result trimming).

Once we cap max_file_match_results, FileMatchCount will reflect the cap (e.g., 20) instead of the true total, making displayed counts incorrect.

Proposal

Update Gitlab::Search::Zoekt::Response to use TotalLineMatchCount / TotalFileMatchCount for display counts:

Key file: ee/lib/gitlab/search/zoekt/response.rb

# Current:
def file_count
  return result[:FileMatchCount] if result[:FileMatchCount].present?
  @file_count ||= result['Files']&.count.to_i
end

def match_count
  return result[:LineMatchCount] if result[:LineMatchCount].present?
  @match_count ||= (result['Files']&.sum { |x| x['LineMatches']&.count }).to_i
end

# Proposed: prefer Total* fields, fall back to current behavior
def file_count
  return result[:TotalFileMatchCount] if result[:TotalFileMatchCount].present?
  return result[:FileMatchCount] if result[:FileMatchCount].present?
  @file_count ||= result['Files']&.count.to_i
end

def match_count
  return result[:TotalLineMatchCount] if result[:TotalLineMatchCount].present?
  return result[:LineMatchCount] if result[:LineMatchCount].present?
  @match_count ||= (result['Files']&.sum { |x| x['LineMatches']&.count }).to_i
end

Rollout

This change should be rolled out behind a feature flag (e.g., zoekt_use_total_match_counts) to allow gradual rollout and quick rollback.

Edited by Dmitry Gruzd