A facet is an aggregation over a set of matching documents
Search ranking and facet aggregation do different work. Ranking may return only the top ten documents. The sidebar must often count all matching documents by category or color, even those far below page one. Implementing facets by looking at the first ten hits would be obviously wrong. The system needs an aggregation over the intended document set.
For exact-match filters such as brand, color, and product type, keyword-like fields with column-oriented doc values are a natural fit for many engines. They support sorting and aggregation without requiring those fields to be analyzed like prose. An analyzed text field for "dark red" might contain separate terms dark and red and is not automatically suitable for a stable facet value. Elasticsearch documents that terms aggregations generally use keyword, numeric, boolean, IP, or similar aggregatable field types, with important memory implications if text fielddata is enabled.
Now define the filtering semantics. A search for "winter jacket" might apply query text, region availability, current tenant visibility, and a not-deleted condition. Those are mandatory constraints. If the shopper selects Brand A, we may show color counts within Brand A, while the brand list may show how many matches other brands would have if the current brand selection were removed. The latter is often called disjunctive faceting. It is a product choice, not an engine default.
In Elasticsearch, the difference between a filter in the search query and post_filter can matter. A post_filter can narrow the returned hits after aggregations have been calculated. This can be useful for a specific facet UI, but a careless choice shows counts for a larger population than the visible results. Write tests that state the intended population for each sidebar number.
Distributed counting can introduce another disagreement
Assume twenty shards compute a top-ten list of categories by document count. Each shard has thousands of categories. A category might rank eleventh on every shard and never be sent to the coordinator, yet still be a global leader: each shard can have ten different local-only categories with 101 documents each, while the shared category has 100 on each of twenty shards, or 2,000 overall. Returning more buckets per shard reduces that risk but increases per-shard work, network payload and coordinator memory.
Elasticsearch's terms aggregation requests more candidates than the final size through shard_size. Its documented default is approximately size * 1.5 + 10. Under the usual descending-count order, result counts can still be approximate because some shard contributions were not sent. The response exposes fields such as doc_count_error_upper_bound and sum_other_doc_count, with qualifications. A zero error in a supported case is meaningful. A nonzero upper bound should not silently be displayed as an exact inventory count.
Increasing shard count does not inherently improve accuracy. It may increase opportunities for local truncation and coordinator fanout, depending on data distribution and configuration. And increasing size indiscriminately can push aggregation memory and bucket limits beyond acceptable bounds. We should choose between top categories with documented approximation and an exact answer for a known selected category.
An exact "How many red jackets?" count can be computed with a filtered counting query over all matching shards and a consistent search view, assuming the underlying count API semantics and filters support that guarantee. That can cost more than asking for the largest ten facets. Product requirements should decide which counts must be exact and which may be estimates marked as such.
Make the disagreement observable
My investigation would capture one query ID and the full effective query and filter set for both the sidebar and clicked result page. I would log which indices, shard copies, routing parameters, refresh snapshots, aggregation size, shard_size, and error metadata were involved. Then run a controlled test on a frozen dataset with known counts. That separates approximation from freshness and filter mismatch.
Privacy cannot be an afterthought. If user-specific availability or tenant policy is applied only when fetching hits, a global facet count can leak that hidden products exist. Mandatory authorization constraints must apply to aggregation as well as retrieval, and the security boundary should not rely solely on a UI filter.
Inventory changes can also make the first and second pages disagree over time. For a bounded shopping interaction, decide whether to favor freshest counts or a stable point-in-time view. A PIT can stabilize search snapshots for a session when appropriate, though it does not validate authoritative checkout inventory and carries resource cost.
The answer I would look for in an interview is define the counted population, use appropriate columnar facet fields, understand shard-local candidate truncation, and choose explicit accuracy semantics. Shard capacity is a scaling concern, not a substitute for these decisions.