_all: Stop NPE querying _all when it doesn't exist

This can happen in two ways:
1. The _all field is disabled.
2. There are documents in the index, the _all field is enabled, but there are
no fields in any of the documents.

In both of these cases we now rewrite the query to a MatchNoDocsQuery which
should be safe because there isn't anything to match.

Closes #12439
This commit is contained in:
Nik Everett 2015-07-27 15:36:34 -04:00
parent 15ea07f8c0
commit d7491515b2
2 changed files with 29 additions and 3 deletions

View File

@ -25,6 +25,7 @@ import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchNoDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.payloads.AveragePayloadFunction;
@ -124,14 +125,21 @@ public final class AllTermQuery extends PayloadTermQuery {
@Override
public Query rewrite(IndexReader reader) throws IOException {
boolean fieldExists = false;
boolean hasPayloads = false;
for (LeafReaderContext context : reader.leaves()) {
final Terms terms = context.reader().terms(term.field());
if (terms.hasPayloads()) {
hasPayloads = true;
break;
if (terms != null) {
fieldExists = true;
if (terms.hasPayloads()) {
hasPayloads = true;
break;
}
}
}
if (fieldExists == false) {
return new MatchNoDocsQuery();
}
if (hasPayloads == false) {
TermQuery rewritten = new TermQuery(term);
rewritten.setBoost(getBoost());

View File

@ -1867,6 +1867,24 @@ public class SearchQueryTests extends ElasticsearchIntegrationTest {
assertHitCount(searchResponse, 1l);
}
@Test
public void testAllFieldEmptyMapping() throws Exception {
client().prepareIndex("myindex", "mytype").setId("1").setSource("{}").setRefresh(true).get();
SearchResponse response = client().prepareSearch("myindex").setQuery(matchQuery("_all", "foo")).get();
assertNoFailures(response);
}
@Test
public void testAllDisabledButQueried() throws Exception {
createIndex("myindex");
assertAcked(client().admin().indices().preparePutMapping("myindex").setType("mytype").setSource(
jsonBuilder().startObject().startObject("mytype").startObject("_all").field("enabled", false)));
client().prepareIndex("myindex", "mytype").setId("1").setSource("bar", "foo").setRefresh(true).get();
SearchResponse response = client().prepareSearch("myindex").setQuery(matchQuery("_all", "foo")).get();
assertNoFailures(response);
assertHitCount(response, 0);
}
@Test
public void testIndicesQuery() throws Exception {
createIndex("index1", "index2", "index3");