Open vibrantvarun opened 1 month ago
Solution:
Increment the total hit count as soon as it comes in the collector.
Code changes
@Getter
protected int totalHits;
collector.getTotalhits()
Improvement in Latency
(number of shards)x(Iteration over number of unique score docs in Query Phase + Normalization Phase)
Great finding and analysis. Solution looks good, I have few minor questions regarding implementation but we can address them in PR review.
As it promising some cut on CPU cycles we can add this issue to the https://github.com/opensearch-project/neural-search/issues/704 meta issue for performance improvements. Before we can do that please collect benchmark results on how much boost this change can give us. You can take on the issues from https://github.com/opensearch-project/neural-search/issues/704 as a template
Is this gradlew check failure related? https://github.com/opensearch-project/neural-search/actions/runs/9217921363/job/25360650184?pr=744
Does anyone know whether this is a longstanding issue or something new introduced with the release of 2.14 a week ago?
Does anyone know whether this is a longstanding issue or something new introduced with the release of 2.14 a week ago?
It was correct from the initial release of hybrid query, in 2.10 code was different but with same semantics - total hits per sub query are calculated for each matching doc id, then we select max out of all total hits per sub query, code ref from 2.10 in 2.13 the bug creeped it, and the same code is in 2.14 - https://github.com/opensearch-project/neural-search/blob/2.13/src/main/java/org/opensearch/neuralsearch/processor/combination/ScoreCombiner.java#L140-L146
to summarize - correct logic was in 2.10 to 2.12, then bug is introduced in 2.13. Fix will be available in 2.15
| Metric | Task | Value | Unit |
|---------------------------------------------------------------:|----------------------------------------------------------------------:|------------:|-------:|
| Cumulative indexing time of primary shards | | 3.95873 | min |
| Min cumulative indexing time across primary shards | | 0.000166667 | min |
| Median cumulative indexing time across primary shards | | 0.66145 | min |
| Max cumulative indexing time across primary shards | | 0.673883 | min |
| Cumulative indexing throttle time of primary shards | | 0 | min |
| Min cumulative indexing throttle time across primary shards | | 0 | min |
| Median cumulative indexing throttle time across primary shards | | 0 | min |
| Max cumulative indexing throttle time across primary shards | | 0 | min |
| Cumulative merge time of primary shards | | 0.2149 | min |
| Cumulative merge count of primary shards | | 12 | |
| Min cumulative merge time across primary shards | | 0 | min |
| Median cumulative merge time across primary shards | | 0.0286167 | min |
| Max cumulative merge time across primary shards | | 0.05535 | min |
| Cumulative merge throttle time of primary shards | | 0 | min |
| Min cumulative merge throttle time across primary shards | | 0 | min |
| Median cumulative merge throttle time across primary shards | | 0 | min |
| Max cumulative merge throttle time across primary shards | | 0 | min |
| Cumulative refresh time of primary shards | | 0.247 | min |
| Cumulative refresh count of primary shards | | 107 | |
| Min cumulative refresh time across primary shards | | 0.000466667 | min |
| Median cumulative refresh time across primary shards | | 0.04055 | min |
| Max cumulative refresh time across primary shards | | 0.0453 | min |
| Cumulative flush time of primary shards | | 0.000933333 | min |
| Cumulative flush count of primary shards | | 7 | |
| Min cumulative flush time across primary shards | | 0 | min |
| Median cumulative flush time across primary shards | | 0 | min |
| Max cumulative flush time across primary shards | | 0.000933333 | min |
| Total Young Gen GC time | | 2.239 | s |
| Total Young Gen GC count | | 202 | |
| Total Old Gen GC time | | 0 | s |
| Total Old Gen GC count | | 0 | |
| Store size | | 0.359066 | GB |
| Translog size | | 3.58559e-07 | GB |
| Heap used for segments | | 0 | MB |
| Heap used for doc values | | 0 | MB |
| Heap used for terms | | 0 | MB |
| Heap used for norms | | 0 | MB |
| Heap used for points | | 0 | MB |
| Heap used for stored fields | | 0 | MB |
| Segment count | | 46 | |
| error rate | index | 0 | % |
| Min Throughput | wait-until-merges-finish | 67.7 | ops/s |
| Mean Throughput | wait-until-merges-finish | 67.7 | ops/s |
| Median Throughput | wait-until-merges-finish | 67.7 | ops/s |
| Max Throughput | wait-until-merges-finish | 67.7 | ops/s |
| 100th percentile latency | wait-until-merges-finish | 14.3871 | ms |
| 100th percentile service time | wait-until-merges-finish | 14.3871 | ms |
| error rate | wait-until-merges-finish | 0 | % |
| Min Throughput | hybrid-query-only-range | 2.02 | ops/s |
| Mean Throughput | hybrid-query-only-range | 2.03 | ops/s |
| Median Throughput | hybrid-query-only-range | 2.03 | ops/s |
| Max Throughput | hybrid-query-only-range | 2.07 | ops/s |
| 50th percentile latency | hybrid-query-only-range | 8.93327 | ms |
| 90th percentile latency | hybrid-query-only-range | 10.6464 | ms |
| 99th percentile latency | hybrid-query-only-range | 11.7067 | ms |
| 100th percentile latency | hybrid-query-only-range | 11.7693 | ms |
| 50th percentile service time | hybrid-query-only-range | 6.94127 | ms |
| 90th percentile service time | hybrid-query-only-range | 8.72685 | ms |
| 99th percentile service time | hybrid-query-only-range | 9.74384 | ms |
| 100th percentile service time | hybrid-query-only-range | 9.893 | ms |
| error rate | hybrid-query-only-range | 0 | % |
| Min Throughput | bool-only-range | 2.02 | ops/s |
| Mean Throughput | bool-only-range | 2.03 | ops/s |
| Median Throughput | bool-only-range | 2.03 | ops/s |
| Max Throughput | bool-only-range | 2.08 | ops/s |
| 50th percentile latency | bool-only-range | 13.803 | ms |
| 90th percentile latency | bool-only-range | 21.8909 | ms |
| 99th percentile latency | bool-only-range | 26.8706 | ms |
| 100th percentile latency | bool-only-range | 41.5655 | ms |
| 50th percentile service time | bool-only-range | 11.9204 | ms |
| 90th percentile service time | bool-only-range | 19.8631 | ms |
| 99th percentile service time | bool-only-range | 24.4801 | ms |
| 100th percentile service time | bool-only-range | 38.208 | ms |
| error rate | bool-only-range | 0 | % |
| Min Throughput | aggs query for min, avg and sum for one subquery case | 2.01 | ops/s |
| Mean Throughput | aggs query for min, avg and sum for one subquery case | 2.03 | ops/s |
| Median Throughput | aggs query for min, avg and sum for one subquery case | 2.02 | ops/s |
| Max Throughput | aggs query for min, avg and sum for one subquery case | 2.06 | ops/s |
| 50th percentile latency | aggs query for min, avg and sum for one subquery case | 47.3007 | ms |
| 90th percentile latency | aggs query for min, avg and sum for one subquery case | 51.8938 | ms |
| 99th percentile latency | aggs query for min, avg and sum for one subquery case | 56.0839 | ms |
| 100th percentile latency | aggs query for min, avg and sum for one subquery case | 59.7897 | ms |
| 50th percentile service time | aggs query for min, avg and sum for one subquery case | 45.3641 | ms |
| 90th percentile service time | aggs query for min, avg and sum for one subquery case | 49.8488 | ms |
| 99th percentile service time | aggs query for min, avg and sum for one subquery case | 52.6064 | ms |
| 100th percentile service time | aggs query for min, avg and sum for one subquery case | 54.9282 | ms |
| error rate | aggs query for min, avg and sum for one subquery case | 0 | % |
| Min Throughput | aggs-query-min-avg-sum-bool-one-subquery | 2.02 | ops/s |
| Mean Throughput | aggs-query-min-avg-sum-bool-one-subquery | 2.03 | ops/s |
| Median Throughput | aggs-query-min-avg-sum-bool-one-subquery | 2.03 | ops/s |
| Max Throughput | aggs-query-min-avg-sum-bool-one-subquery | 2.08 | ops/s |
| 50th percentile latency | aggs-query-min-avg-sum-bool-one-subquery | 12.2088 | ms |
| 90th percentile latency | aggs-query-min-avg-sum-bool-one-subquery | 19.8682 | ms |
| 99th percentile latency | aggs-query-min-avg-sum-bool-one-subquery | 23.4455 | ms |
| 100th percentile latency | aggs-query-min-avg-sum-bool-one-subquery | 24.2925 | ms |
| 50th percentile service time | aggs-query-min-avg-sum-bool-one-subquery | 10.0337 | ms |
| 90th percentile service time | aggs-query-min-avg-sum-bool-one-subquery | 18.0666 | ms |
| 99th percentile service time | aggs-query-min-avg-sum-bool-one-subquery | 21.7575 | ms |
| 100th percentile service time | aggs-query-min-avg-sum-bool-one-subquery | 22.077 | ms |
| error rate | aggs-query-min-avg-sum-bool-one-subquery | 0 | % |
| Min Throughput | aggs-query-min-avg-sum-hybrid-one-subquery | 2.02 | ops/s |
| Mean Throughput | aggs-query-min-avg-sum-hybrid-one-subquery | 2.03 | ops/s |
| Median Throughput | aggs-query-min-avg-sum-hybrid-one-subquery | 2.03 | ops/s |
| Max Throughput | aggs-query-min-avg-sum-hybrid-one-subquery | 2.08 | ops/s |
| 50th percentile latency | aggs-query-min-avg-sum-hybrid-one-subquery | 10.2761 | ms |
| 90th percentile latency | aggs-query-min-avg-sum-hybrid-one-subquery | 11.729 | ms |
| 99th percentile latency | aggs-query-min-avg-sum-hybrid-one-subquery | 13.6919 | ms |
| 100th percentile latency | aggs-query-min-avg-sum-hybrid-one-subquery | 13.8546 | ms |
| 50th percentile service time | aggs-query-min-avg-sum-hybrid-one-subquery | 8.16763 | ms |
| 90th percentile service time | aggs-query-min-avg-sum-hybrid-one-subquery | 9.58318 | ms |
| 99th percentile service time | aggs-query-min-avg-sum-hybrid-one-subquery | 11.3461 | ms |
| 100th percentile service time | aggs-query-min-avg-sum-hybrid-one-subquery | 12.1772 | ms |
| error rate | aggs-query-min-avg-sum-hybrid-one-subquery | 0 | % |
| Min Throughput | aggs query for term and min for one subquery case | 2.01 | ops/s |
| Mean Throughput | aggs query for term and min for one subquery case | 2.02 | ops/s |
| Median Throughput | aggs query for term and min for one subquery case | 2.01 | ops/s |
| Max Throughput | aggs query for term and min for one subquery case | 2.04 | ops/s |
| 50th percentile latency | aggs query for term and min for one subquery case | 69.224 | ms |
| 90th percentile latency | aggs query for term and min for one subquery case | 70.6339 | ms |
| 99th percentile latency | aggs query for term and min for one subquery case | 74.5619 | ms |
| 100th percentile latency | aggs query for term and min for one subquery case | 127.438 | ms |
| 50th percentile service time | aggs query for term and min for one subquery case | 67.2896 | ms |
| 90th percentile service time | aggs query for term and min for one subquery case | 68.5886 | ms |
| 99th percentile service time | aggs query for term and min for one subquery case | 72.066 | ms |
| 100th percentile service time | aggs query for term and min for one subquery case | 125.615 | ms |
| error rate | aggs query for term and min for one subquery case | 0 | % |
| Min Throughput | aggs-query-term-min-bool-one-subquery | 2.02 | ops/s |
| Mean Throughput | aggs-query-term-min-bool-one-subquery | 2.03 | ops/s |
| Median Throughput | aggs-query-term-min-bool-one-subquery | 2.03 | ops/s |
| Max Throughput | aggs-query-term-min-bool-one-subquery | 2.08 | ops/s |
| 50th percentile latency | aggs-query-term-min-bool-one-subquery | 9.94758 | ms |
| 90th percentile latency | aggs-query-term-min-bool-one-subquery | 11.3565 | ms |
| 99th percentile latency | aggs-query-term-min-bool-one-subquery | 15.9427 | ms |
| 100th percentile latency | aggs-query-term-min-bool-one-subquery | 32.7745 | ms |
| 50th percentile service time | aggs-query-term-min-bool-one-subquery | 7.99819 | ms |
| 90th percentile service time | aggs-query-term-min-bool-one-subquery | 9.41365 | ms |
| 99th percentile service time | aggs-query-term-min-bool-one-subquery | 13.8923 | ms |
| 100th percentile service time | aggs-query-term-min-bool-one-subquery | 28.2762 | ms |
| error rate | aggs-query-term-min-bool-one-subquery | 0 | % |
| Min Throughput | aggs-query-term-min-hybrid-one-subquery | 2.02 | ops/s |
| Mean Throughput | aggs-query-term-min-hybrid-one-subquery | 2.03 | ops/s |
| Median Throughput | aggs-query-term-min-hybrid-one-subquery | 2.03 | ops/s |
| Max Throughput | aggs-query-term-min-hybrid-one-subquery | 2.08 | ops/s |
| 50th percentile latency | aggs-query-term-min-hybrid-one-subquery | 10.2546 | ms |
| 90th percentile latency | aggs-query-term-min-hybrid-one-subquery | 12.0127 | ms |
| 99th percentile latency | aggs-query-term-min-hybrid-one-subquery | 12.9903 | ms |
| 100th percentile latency | aggs-query-term-min-hybrid-one-subquery | 13.009 | ms |
| 50th percentile service time | aggs-query-term-min-hybrid-one-subquery | 7.83035 | ms |
| 90th percentile service time | aggs-query-term-min-hybrid-one-subquery | 9.57152 | ms |
| 99th percentile service time | aggs-query-term-min-hybrid-one-subquery | 10.5338 | ms |
| 100th percentile service time | aggs-query-term-min-hybrid-one-subquery | 10.6379 | ms |
| error rate | aggs-query-term-min-hybrid-one-subquery | 0 | % |
| Min Throughput | aggs query for date historgram and geohash grid for one subquery case | 2.01 | ops/s |
| Mean Throughput | aggs query for date historgram and geohash grid for one subquery case | 2.02 | ops/s |
| Median Throughput | aggs query for date historgram and geohash grid for one subquery case | 2.02 | ops/s |
| Max Throughput | aggs query for date historgram and geohash grid for one subquery case | 2.04 | ops/s |
| 50th percentile latency | aggs query for date historgram and geohash grid for one subquery case | 108.927 | ms |
| 90th percentile latency | aggs query for date historgram and geohash grid for one subquery case | 111.453 | ms |
| 99th percentile latency | aggs query for date historgram and geohash grid for one subquery case | 115.845 | ms |
| 100th percentile latency | aggs query for date historgram and geohash grid for one subquery case | 118.2 | ms |
| 50th percentile service time | aggs query for date historgram and geohash grid for one subquery case | 106.87 | ms |
| 90th percentile service time | aggs query for date historgram and geohash grid for one subquery case | 109.487 | ms |
| 99th percentile service time | aggs query for date historgram and geohash grid for one subquery case | 112.402 | ms |
| 100th percentile service time | aggs query for date historgram and geohash grid for one subquery case | 113.99 | ms |
| error rate | aggs query for date historgram and geohash grid for one subquery case | 0 | % |
| Min Throughput | aggs-query-date-histo-geohash-grid-bool-one-subquery | 2.02 | ops/s |
| Mean Throughput | aggs-query-date-histo-geohash-grid-bool-one-subquery | 2.03 | ops/s |
| Median Throughput | aggs-query-date-histo-geohash-grid-bool-one-subquery | 2.03 | ops/s |
| Max Throughput | aggs-query-date-histo-geohash-grid-bool-one-subquery | 2.08 | ops/s |
| 50th percentile latency | aggs-query-date-histo-geohash-grid-bool-one-subquery | 8.71025 | ms |
| 90th percentile latency | aggs-query-date-histo-geohash-grid-bool-one-subquery | 10.054 | ms |
| 99th percentile latency | aggs-query-date-histo-geohash-grid-bool-one-subquery | 11.4456 | ms |
| 100th percentile latency | aggs-query-date-histo-geohash-grid-bool-one-subquery | 12.3663 | ms |
| 50th percentile service time | aggs-query-date-histo-geohash-grid-bool-one-subquery | 6.80454 | ms |
| 90th percentile service time | aggs-query-date-histo-geohash-grid-bool-one-subquery | 8.1457 | ms |
| 99th percentile service time | aggs-query-date-histo-geohash-grid-bool-one-subquery | 9.49472 | ms |
| 100th percentile service time | aggs-query-date-histo-geohash-grid-bool-one-subquery | 10.7954 | ms |
| error rate | aggs-query-date-histo-geohash-grid-bool-one-subquery | 0 | % |
| Min Throughput | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 2.02 | ops/s |
| Mean Throughput | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 2.03 | ops/s |
| Median Throughput | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 2.03 | ops/s |
| Max Throughput | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 2.08 | ops/s |
| 50th percentile latency | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 8.99458 | ms |
| 90th percentile latency | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 10.3031 | ms |
| 99th percentile latency | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 11.1168 | ms |
| 100th percentile latency | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 14.8614 | ms |
| 50th percentile service time | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 6.95075 | ms |
| 90th percentile service time | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 8.2676 | ms |
| 99th percentile service time | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 8.99551 | ms |
| 100th percentile service time | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 13.1216 | ms |
| error rate | aggs-query-date-histo-geohash-grid-hybrid-one-subquery | 0 | % |
| Min Throughput | aggs query for range and significant terms for one subquery case | 2.01 | ops/s |
| Mean Throughput | aggs query for range and significant terms for one subquery case | 2.02 | ops/s |
| Median Throughput | aggs query for range and significant terms for one subquery case | 2.01 | ops/s |
| Max Throughput | aggs query for range and significant terms for one subquery case | 2.04 | ops/s |
| 50th percentile latency | aggs query for range and significant terms for one subquery case | 181.658 | ms |
| 90th percentile latency | aggs query for range and significant terms for one subquery case | 189.614 | ms |
| 99th percentile latency | aggs query for range and significant terms for one subquery case | 194.823 | ms |
| 100th percentile latency | aggs query for range and significant terms for one subquery case | 194.954 | ms |
| 50th percentile service time | aggs query for range and significant terms for one subquery case | 178.892 | ms |
| 90th percentile service time | aggs query for range and significant terms for one subquery case | 187.808 | ms |
| 99th percentile service time | aggs query for range and significant terms for one subquery case | 191.871 | ms |
| 100th percentile service time | aggs query for range and significant terms for one subquery case | 193.608 | ms |
| error rate | aggs query for range and significant terms for one subquery case | 0 | % |
| Min Throughput | aggs-query-range-numeric-significant-terms-bool-one-subquery | 2.02 | ops/s |
| Mean Throughput | aggs-query-range-numeric-significant-terms-bool-one-subquery | 2.03 | ops/s |
| Median Throughput | aggs-query-range-numeric-significant-terms-bool-one-subquery | 2.03 | ops/s |
| Max Throughput | aggs-query-range-numeric-significant-terms-bool-one-subquery | 2.08 | ops/s |
| 50th percentile latency | aggs-query-range-numeric-significant-terms-bool-one-subquery | 18.0933 | ms |
| 90th percentile latency | aggs-query-range-numeric-significant-terms-bool-one-subquery | 21.1245 | ms |
| 99th percentile latency | aggs-query-range-numeric-significant-terms-bool-one-subquery | 25.2007 | ms |
| 100th percentile latency | aggs-query-range-numeric-significant-terms-bool-one-subquery | 26.486 | ms |
| 50th percentile service time | aggs-query-range-numeric-significant-terms-bool-one-subquery | 16.2044 | ms |
| 90th percentile service time | aggs-query-range-numeric-significant-terms-bool-one-subquery | 18.7054 | ms |
| 99th percentile service time | aggs-query-range-numeric-significant-terms-bool-one-subquery | 23.0979 | ms |
| 100th percentile service time | aggs-query-range-numeric-significant-terms-bool-one-subquery | 23.1119 | ms |
| error rate | aggs-query-range-numeric-significant-terms-bool-one-subquery | 0 | % |
| Min Throughput | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 2.02 | ops/s |
| Mean Throughput | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 2.03 | ops/s |
| Median Throughput | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 2.03 | ops/s |
| Max Throughput | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 2.08 | ops/s |
| 50th percentile latency | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 19.4735 | ms |
| 90th percentile latency | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 22.7889 | ms |
| 99th percentile latency | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 28.8049 | ms |
| 100th percentile latency | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 35.8238 | ms |
| 50th percentile service time | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 17.0495 | ms |
| 90th percentile service time | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 20.6409 | ms |
| 99th percentile service time | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 26.1562 | ms |
| 100th percentile service time | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 31.8815 | ms |
| error rate | aggs-query-range-numeric-significant-terms-hybrid-one-subquery | 0 | % |
What is the bug?
The total count is wrong when size is given in the search request. For example When I hit the search request with Hybrid query with url below
I get
But When I hit the search request by adding size =1 I get different hit count
the response is
How can one reproduce the bug?
What is the expected behavior?
Number of total hits should be consistent.
Do you have any additional context?
The reason why this bug is coming because we calculate totalhits per shard by identifying the number of unique docId's in the result here. The query result per shard is based on numHits here. The numHits is nothing but the size sent in the search request. So for every shard it will get only 1 doc in the query result. But, collector will get the complete result irrespective of what size is given in the search request. size parameter aka numhits is always used to cut the result into size what user wants.
Let's try understand with an example
I have created my-nlp-index which has 3 shards. I have given 2 subqueries and size=1 in the search request.
Shard 1 Consider, the collector will collect the matching results(The count of the results is 40) but the when topDocs will be determined from the matching results it size would be 1 per subquery. Remaining 39 documents won't be added in the topDocs. Later, when we calculate total hits we will just calculate the unique docId's on the shard from both the subqueries. Consider that unique docId count to be 2.
Shard 2 If the same count(40) of results we got on shard 2 as well and the unique docId count is 2.
Therefore, with the current workflow the search response would have 4 as total hits. But, the actual total hit is 80.