Browse Source

Enable option to use request cache for size > 0

Previously if the size of the search request was greater than zero we would not cache the request in the request cache.

This change retains the default behaviour of not caching requests with size > 0 but also allows the `request_cache=true` query parameter
to enable the cache for requests with size > 0
Colin Goodheart-Smithe 9 years ago
parent
commit
b717ad8eb6

+ 4 - 4
core/src/main/java/org/elasticsearch/indices/IndicesService.java

@@ -1051,10 +1051,6 @@ public class IndicesService extends AbstractLifecycleComponent
      * Can the shard request be cached at all?
      */
     public boolean canCache(ShardSearchRequest request, SearchContext context) {
-        // for now, only enable it for requests with no hits
-        if (context.size() != 0) {
-            return false;
-        }
 
         // We cannot cache with DFS because results depend not only on the content of the index but also
         // on the overridden statistics. So if you ran two queries on the same index with different stats
@@ -1068,6 +1064,10 @@ public class IndicesService extends AbstractLifecycleComponent
         if (request.requestCache() == null) {
             if (settings.getValue(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING) == false) {
                 return false;
+            } else if (context.size() != 0) {
+                // If no request cache query parameter and shard request cache
+                // is enabled in settings don't cache for requests with size > 0
+                return false;
             }
         } else if (request.requestCache() == false) {
             return false;

+ 63 - 0
core/src/test/java/org/elasticsearch/indices/IndicesRequestCacheIT.java

@@ -354,4 +354,67 @@ public class IndicesRequestCacheIT extends ESIntegTestCase {
                 equalTo(0L));
     }
 
+    public void testCanCache() throws Exception {
+        assertAcked(client().admin().indices().prepareCreate("index").addMapping("type", "s", "type=date")
+                .setSettings(IndicesRequestCache.INDEX_CACHE_REQUEST_ENABLED_SETTING.getKey(), true, IndexMetaData.SETTING_NUMBER_OF_SHARDS,
+                        5, IndexMetaData.SETTING_NUMBER_OF_REPLICAS, 0)
+                .get());
+        indexRandom(true, client().prepareIndex("index", "type", "1").setRouting("1").setSource("s", "2016-03-19"),
+                client().prepareIndex("index", "type", "2").setRouting("1").setSource("s", "2016-03-20"),
+                client().prepareIndex("index", "type", "3").setRouting("1").setSource("s", "2016-03-21"),
+                client().prepareIndex("index", "type", "4").setRouting("2").setSource("s", "2016-03-22"),
+                client().prepareIndex("index", "type", "5").setRouting("2").setSource("s", "2016-03-23"),
+                client().prepareIndex("index", "type", "6").setRouting("2").setSource("s", "2016-03-24"),
+                client().prepareIndex("index", "type", "7").setRouting("3").setSource("s", "2016-03-25"),
+                client().prepareIndex("index", "type", "8").setRouting("3").setSource("s", "2016-03-26"),
+                client().prepareIndex("index", "type", "9").setRouting("3").setSource("s", "2016-03-27"));
+        ensureSearchable("index");
+
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
+                equalTo(0L));
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getMissCount(),
+                equalTo(0L));
+
+        // If size > 0 we should no cache by default
+        final SearchResponse r1 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(1)
+                .setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-19").lte("2016-03-25")).get();
+        assertSearchResponse(r1);
+        assertThat(r1.getHits().getTotalHits(), equalTo(7L));
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
+                equalTo(0L));
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getMissCount(),
+                equalTo(0L));
+
+        // If search type is DFS_QUERY_THEN_FETCH we should not cache
+        final SearchResponse r2 = client().prepareSearch("index").setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setSize(0)
+                .setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-20").lte("2016-03-26")).get();
+        assertSearchResponse(r2);
+        assertThat(r2.getHits().getTotalHits(), equalTo(7L));
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
+                equalTo(0L));
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getMissCount(),
+                equalTo(0L));
+
+        // If search type is DFS_QUERY_THEN_FETCH we should not cache even if
+        // the cache flag is explicitly set on the request
+        final SearchResponse r3 = client().prepareSearch("index").setSearchType(SearchType.DFS_QUERY_THEN_FETCH).setSize(0)
+                .setRequestCache(true).setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-20").lte("2016-03-26")).get();
+        assertSearchResponse(r3);
+        assertThat(r3.getHits().getTotalHits(), equalTo(7L));
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
+                equalTo(0L));
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getMissCount(),
+                equalTo(0L));
+
+        // If size > 1 and cache flag is set on the request we should cache
+        final SearchResponse r4 = client().prepareSearch("index").setSearchType(SearchType.QUERY_THEN_FETCH).setSize(1)
+                .setRequestCache(true).setQuery(QueryBuilders.rangeQuery("s").gte("2016-03-21").lte("2016-03-27")).get();
+        assertSearchResponse(r4);
+        assertThat(r4.getHits().getTotalHits(), equalTo(7L));
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getHitCount(),
+                equalTo(0L));
+        assertThat(client().admin().indices().prepareStats("index").setRequestCache(true).get().getTotal().getRequestCache().getMissCount(),
+                equalTo(5L));
+    }
+
 }

+ 5 - 1
docs/reference/modules/indices/request_cache.asciidoc

@@ -15,7 +15,7 @@ results from older indices will be served directly from the cache.
 [IMPORTANT]
 ===================================
 
-For now, the requests cache will only cache the results of search requests
+By default, the requests cache will only cache the results of search requests
 where `size=0`, so it will not cache `hits`,
 but it will cache `hits.total`,  <<search-aggregations,aggregations>>, and
 <<search-suggesters,suggestions>>.
@@ -98,6 +98,10 @@ IMPORTANT: If your query uses a script whose result is not deterministic (e.g.
 it uses a random function or references the current time) you should set the
 `request_cache` flag to `false` to disable caching for that request.
 
+Requests `size` is greater than 0 will not be cached even if the request cache is
+enabled in the index settings. To cache these requests you will need to use the
+query-string parameter detailed here.
+
 [float]
 ==== Cache key