Opensearch Dashboards shows 10000 as hits.total

In Opensearch Dashboards, hits.total is always a maximum value of 10000. This means anything using a Count metric in a Visualization, or in Alerting, ends up with a maximum value of 10000. This also impacts the “Hits (total)” count in Discover. Dashboards is effectively a broken calculator since you cannot work with values over 10000.
We touched on this during the last Community Meeting (Jan 18 2022). It was suggested I post about this again to bring more current visibility to the issue. This is a high-impact bug since it renders most computational features of Dashboards useless.

This bug is present in at least Opensearch Dashboards 1.2.0, and I assume all other versions since I don’t see anything about this in any release notes. I believe the bug was present in Kibana 7.10.2 and was forked over from that project.

Here is a forum post about this same issue from April 2020:

This is the breaking changes documentation for elasticsearch 7.x, which discusses the various bits which are the underlying caused of this bug:

  • track_total_hits is now false by default, which causes the backend to return a hit.total maximum value of 10000. A search must include the parameter track_total_hits: true in order for that search to receive accurate hits.total.
  • hits.total is returned in a different part of the response object than it was before.

https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking-changes-7.0.html#hits-total-now-object-search-response

There are two open bug tickets about this in github already:
https://github.com/opendistro-for-elasticsearch/alerting-kibana-plugin/issues/143
https://github.com/opendistro-for-elasticsearch/alerting-kibana-plugin/issues/89

This is the github issue on the Elastic side, in which they address this hits.total changeover in Kibana:
https://github.com/elastic/kibana/issues/26356

Attached are screenshots illustrating some places where this bug manifests itself in Opensearch Dashboards.




This is a large issue for us as well.

I’m not sure this is an issue in Kibana 7.10.2 as well. At least not the simplest instance, which we run into constantly, which is just seeing how many results matched a query. Kibana 7.10.2 will show us that 34,123,456 results matched, where OpenSearch dashboards will never show more than 10,000. OpenSearch via the REST API will return the total number of results as expected when the track_total_hits param is set to true.

Indeed. I can’t get internal customers to adopt Opensearch Dashboards because of this. It is literally a showstopper bug.

The question is, what’s involved in setting track_total_hits to true in Dashboards. Is all the supporting code for this already in Dashboards and it’s just a matter of toggling it on somewhere?

Is there a temporary workaround or patch that could be used until a fix makes it into a release?

I’ve tried grep’ing through the code and experimenting, myself, trying to find if there’s some single place it can be toggled, but I’ve been unsuccessful.
The best I can find is that trackTotalHits is in fact already set to true in get_default_search_params.ts - but evidently is not being honored for an unknown reason.

1 Like

I believe I might have a change that can fix it [here] but for some reason I can’t recreate the 10,000 count only. Like for me I pulled the latest OpenSearch 1.2.4 executable and latest OpenSearch Dashboards 1.2.0 executable and ran both of them. I created a small document and added to my index.

Here is what I see:

As you can see what I hit it with the dev tools I see:

So my cluster is configured only return back the default amount but the Discover page and others still shows the total hits.

Are you able to share how you are running your stacks or potentially creating a BUG in the repo with recreation steps. If you can’t share an example doc then the mappings would help. Also how your index pattern looks like will also help like (timestamp field and how many indices does it match).

Thank you!

2 Likes

Thanks for this! However, I’m finding my installation of OpenSearch Dashboards (1.2.0) seems to be different than the one you have forked. The files you’ve modified are not similar to the ones I have on disk in my installation. Also, the file suffixes I have are .js, and yours are .ts
I’m going to do a fresh install using your fork and see what happens.

I suspect the only thing special about my setup is that the clusters I’m searching are remote cross-search clusters. I don’t have any data on the cluster local to Dashboards. But that shouldn’t matter, right? I’ll experiment with local data and confirm.

I think you are comparing source code and a compiled / deployed package. Those two are different things. You would need to go through the build process to produce a package that can be installed similar to the downloads you would get from the website.

Hrmm, in that case I’ll be learning the Dashboards build process today.

REVELATION: When searching data on the local cluster, the hits.total count is accurate above 10k. When searching data on remote cross-search configured clusters, the hits.total is always 10000.

This problem appears isolated to remote cross-search clusters? At least, it appears that way for me.

I’ll still try a build of @kavilla 's fork to see if forcing the track_total_hits into the body of the request will fix the hit.total for remote cross-search clusters. Stay tuned…

1 Like

I’ll still try a build of @kavilla 's fork to see if forcing the track_total_hits into the body of the request will fix the hit.total for remote cross-search clusters

Let me know if you would like me to create a 1.2.0 OpenSearch Dashboards distribution with these changes!

I’m looking at an example of the problem right now while doing some other analysis of data in the indexes.
Its may be tough to see, but those bars are over 20k results. However the total results provided in the discover tab is just 10k, when clearly its much more than that, even as shown in the results count histogram.

This was just on the discover tab looking at an index pattern. Nothing special.

I might take you up on that offer of a build, @kavilla. That would accelerate my effort.
(My build environment I’m working with is only 20GB total, and I am running out of disk space as I’m attempting to create the Dashboards build. I’m working on getting more space to build this in…)

Still working on the build. The resulting snapshot doesn’t run, apparently because it doesn’t build/install any of the plugins. Still working on figuring that out.

sudo -u opensearch /usr/share/opensearch-dashboards/bin/opensearch-dashboards-plugin list

^ returns blank result

Do you have access to this linux-x64 distribution and this linux-arm64 distribution of OpenSearch Dashboards?

If so, it has the build with my change and with all the plugins (just a warning it’s not an official release, it did not go through sanity testing).

1 Like

Thanks, @kavilla . I was able to pull your distribution from your link above, and it does start up and is usable.
Unfortunately, the 10000 limit persists, and when I inspect the request body, it does not contain track_total_hits: true.
Also, just to sanity check, I did some grep’ing of your distribution to see if the specific lines in your MR were present in the release. I did not find them (I would expect to find them in /src?).
So it seems maybe we’re somehow not getting your code change in the build, still.

When I try to build from your branch ’ avillk/track_total_hits , the resulting snapshot I get is of the 2.0.0 release with no plugins. The snapshot you’re providing is 1.2.0 with plugins. So I must be doing something wrong during my build process. I am following the build instructions from DEVELOPER_GUIDE.md. Specifically, here are the steps I am using:

git clone https://github.com/kavilla/OpenSearch-Dashboards-1.git
cd OpenSearch-Dashboards-1
git checkout avillk/track_total_hits
nvm use
npm i -g yarn
yarn osd bootstrap 
yarn build --skip-os-packages

Am I missing a step that would base me on the 1.2.0 release? Instead of the 2.0.0 release?

Thanks again, I will keep trudging at it on my end.

Unfortunately, the 10000 limit persists, and when I inspect the request body, it does not contain track_total_hits: true.

I see, can you go to the dev tools page and hit your index pattern like the following:
GET /opensearch_dashboards_sample_data_flights*/_search?track_total_hits=true

Do you get the correct amount?

Also, just to sanity check, I did some grep’ing of your distribution to see if the specific lines in your MR were present in the release. I did not find them (I would expect to find them in /src?).

The lines add were compiled down to JS so I would search for the strings only since the source will look a little different.

When I try to build from your branch ’ avillk/track_total_hits , the resulting snapshot I get is of the 2.0.0 release with no plugins. The snapshot you’re providing is 1.2.0 with plugins. So I must be doing something wrong during my build process.

Yeah main is on 2.0.0 but for this I also created a 1.2.0 branch https://github.com/kavilla/OpenSearch-Dashboards-1/tree/avillk/1.2.0/track_total_hits, which checked out on the tag for 1.2.0 and cherry-picked my commits.

For the distribution I’m providing you, it’s actually not just in the OpenSearch Dashboards repos. That will only build snapshots or min versions (without custom plugins from @opensearch-project). So what I’m using is https://github.com/opensearch-project/opensearch-build. This has manifests that can create builds so I’m using this https://github.com/kavilla/opensearch-build/blob/avillk/1.2.0/track_total_hits/manifests/1.2.0/opensearch-dashboards-1.2.0.yml. Then creating a build using Jenkins but can also do it locally like:

# defaults to linux x64 but you can build arm64 by passing `-a arm64`
./build.sh manifests/1.2.0/opensearch-dashboards-1.2.0.yml
# then after it builds run the following
./assemble.sh builds/opensearch-dashboards/manifest.yml 

I added another change but it explicitly passes the trackTotalHits in the Discover page. I just checked the legacy app for 7.10.2 and I don’t actually see them passing trackTotalHits on the Discover page as well. But just verify you said this was working for the legacy app 7.10.2? So even with the previous changes visualizations was still failing? (Alerting might need to explicitly pass this param if something in OpenSearch defaults track_total_hits to false).

I will have a distribution with the discover page in a few minutes for you.

1 Like

When I execute the following in the Dev Tools page, I do get the accurate value in hits.total in the response.

GET /es1:device-web-event-*/_search?track_total_hits=true

However, this behavior is the same in both your patched distribution, and the native 1.2.0 distribution.

1 Like

Here are the OpenSearch Dashboards distributions with the explicit param (warning again: not official it did not go through sanity testing):

Thanks @kavilla . I’m running the new distribution you just posted ~10min ago, and I’m getting the same behavior, maximum hits.total displayed in Discover and in Visualize is 10000. When inspecting the Request body, track_total_hits: true is still not present.



And when I used the Dev Tools page like you suggested, the response there does contain an accurate hits.total

Note that this 10000 limit only appears for remote cross-search clusters. Note my index family I’m searching is prefixed with a cluster name. es1:blahblah-*
When I search local index families, the hits.total is accurate.
When I search remote cross-search clusters, the hits.total is always maximum of 10000.

I’m not running Opensearch 1.2.4.
I’m running Opensearch 1.2.0 and Opensearch Dashbords 1.2.0

Next step on my side, I am going to upgrade Opensearch from 1.2.0 to 1.2.4
(I should do this anyway because log4j blah blah blah)

If this was only the result of the patch level change from .0 to .4, that would be a huge red flag for OpenSearch release management. The screenshot I provided was from a cluster running OpenSearch 1.2.3 and Dashboards 1.2.0. I will try to check out the provided dashboards build in the coming days as time allows.