Made sure that we never throw IndexMissingException in indices query and filter
It could happen although we internally use IgnoreIndices.MISSING, due to MetaData#concreteIndices contract, which throws IndexMissingException anyway if all requested indices are missing. In case all the indices specified in the query/filter are missing, we just execute the no_match query/filter, no need to throw any error. Closes #3428
This commit is contained in:
parent
24434063b6
commit
2cbecd9cb3
|
@ -27,6 +27,7 @@ import org.elasticsearch.common.inject.Inject;
|
|||
import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.common.regex.Regex;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.indices.IndexMissingException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -146,7 +147,15 @@ public class IndicesFilterParser implements FilterParser {
|
|||
}
|
||||
|
||||
protected boolean matchesIndices(String currentIndex, String... indices) {
|
||||
String[] concreteIndices = clusterService.state().metaData().concreteIndices(indices, IgnoreIndices.MISSING, true);
|
||||
final String[] concreteIndices;
|
||||
try {
|
||||
concreteIndices = clusterService.state().metaData().concreteIndices(indices, IgnoreIndices.MISSING, true);
|
||||
} catch(IndexMissingException e) {
|
||||
//Although we use IgnoreIndices.MISSING, according to MetaData#concreteIndices contract,
|
||||
// we get IndexMissing either when we have a single index that is missing or when all indices are missing
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String index : concreteIndices) {
|
||||
if (Regex.simpleMatch(index, currentIndex)) {
|
||||
return true;
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.elasticsearch.common.inject.Inject;
|
|||
import org.elasticsearch.common.lucene.search.Queries;
|
||||
import org.elasticsearch.common.regex.Regex;
|
||||
import org.elasticsearch.common.xcontent.XContentParser;
|
||||
import org.elasticsearch.indices.IndexMissingException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
@ -144,7 +145,15 @@ public class IndicesQueryParser implements QueryParser {
|
|||
}
|
||||
|
||||
protected boolean matchesIndices(String currentIndex, String... indices) {
|
||||
String[] concreteIndices = clusterService.state().metaData().concreteIndices(indices, IgnoreIndices.MISSING, true);
|
||||
final String[] concreteIndices;
|
||||
try {
|
||||
concreteIndices = clusterService.state().metaData().concreteIndices(indices, IgnoreIndices.MISSING, true);
|
||||
} catch(IndexMissingException e) {
|
||||
//Although we use IgnoreIndices.MISSING, according to MetaData#concreteIndices contract,
|
||||
// we get IndexMissing either when we have a single index that is missing or when all indices are missing
|
||||
return false;
|
||||
}
|
||||
|
||||
for (String index : concreteIndices) {
|
||||
if (Regex.simpleMatch(index, currentIndex)) {
|
||||
return true;
|
||||
|
|
|
@ -1686,6 +1686,149 @@ public class SimpleQueryTests extends ElasticsearchIntegrationTest {
|
|||
assertSearchHits(searchResponse, "1", "2");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndicesQueryMissingIndices() throws IOException {
|
||||
createIndex("index1");
|
||||
createIndex("index2");
|
||||
ensureGreen();
|
||||
|
||||
client().prepareIndex("index1", "type1", "1").setSource("field", "match").get();
|
||||
client().prepareIndex("index1", "type1", "2").setSource("field", "no_match").get();
|
||||
client().prepareIndex("index2", "type1", "10").setSource("field", "match").get();
|
||||
client().prepareIndex("index2", "type1", "20").setSource("field", "no_match").get();
|
||||
client().prepareIndex("index3", "type1", "100").setSource("field", "match").get();
|
||||
client().prepareIndex("index3", "type1", "200").setSource("field", "no_match").get();
|
||||
refresh();
|
||||
|
||||
//all indices are missing
|
||||
SearchResponse searchResponse = client().prepareSearch().setQuery(
|
||||
indicesQuery(termQuery("field", "missing"), "test1", "test2", "test3")
|
||||
.noMatchQuery(termQuery("field", "match"))).get();
|
||||
|
||||
assertHitCount(searchResponse, 3l);
|
||||
|
||||
for (SearchHit hit : searchResponse.getHits().getHits()) {
|
||||
if ("index1".equals(hit.index())) {
|
||||
assertThat(hit, hasId("1"));
|
||||
} else if ("index2".equals(hit.index())) {
|
||||
assertThat(hit, hasId("10"));
|
||||
} else if ("index3".equals(hit.index())) {
|
||||
assertThat(hit, hasId("100"));
|
||||
} else {
|
||||
fail("Returned documents should belong to either index1, index2 or index3");
|
||||
}
|
||||
}
|
||||
|
||||
//only one index specified, which is missing
|
||||
searchResponse = client().prepareSearch().setQuery(
|
||||
indicesQuery(termQuery("field", "missing"), "test1")
|
||||
.noMatchQuery(termQuery("field", "match"))).get();
|
||||
|
||||
assertHitCount(searchResponse, 3l);
|
||||
|
||||
for (SearchHit hit : searchResponse.getHits().getHits()) {
|
||||
if ("index1".equals(hit.index())) {
|
||||
assertThat(hit, hasId("1"));
|
||||
} else if ("index2".equals(hit.index())) {
|
||||
assertThat(hit, hasId("10"));
|
||||
} else if ("index3".equals(hit.index())) {
|
||||
assertThat(hit, hasId("100"));
|
||||
} else {
|
||||
fail("Returned documents should belong to either index1, index2 or index3");
|
||||
}
|
||||
}
|
||||
|
||||
//more than one index specified, one of them is missing
|
||||
searchResponse = client().prepareSearch().setQuery(
|
||||
indicesQuery(termQuery("field", "missing"), "index1", "test1")
|
||||
.noMatchQuery(termQuery("field", "match"))).get();
|
||||
|
||||
assertHitCount(searchResponse, 2l);
|
||||
|
||||
for (SearchHit hit : searchResponse.getHits().getHits()) {
|
||||
if ("index2".equals(hit.index())) {
|
||||
assertThat(hit, hasId("10"));
|
||||
} else if ("index3".equals(hit.index())) {
|
||||
assertThat(hit, hasId("100"));
|
||||
} else {
|
||||
fail("Returned documents should belong to either index2 or index3");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIndicesFilterMissingIndices() throws IOException {
|
||||
createIndex("index1");
|
||||
createIndex("index2");
|
||||
ensureGreen();
|
||||
|
||||
client().prepareIndex("index1", "type1", "1").setSource("field", "match").get();
|
||||
client().prepareIndex("index1", "type1", "2").setSource("field", "no_match").get();
|
||||
client().prepareIndex("index2", "type1", "10").setSource("field", "match").get();
|
||||
client().prepareIndex("index2", "type1", "20").setSource("field", "no_match").get();
|
||||
client().prepareIndex("index3", "type1", "100").setSource("field", "match").get();
|
||||
client().prepareIndex("index3", "type1", "200").setSource("field", "no_match").get();
|
||||
refresh();
|
||||
|
||||
//all indices are missing
|
||||
SearchResponse searchResponse = client().prepareSearch().setQuery(
|
||||
filteredQuery(matchAllQuery(),
|
||||
indicesFilter(termFilter("field", "missing"), "test1", "test2", "test3")
|
||||
.noMatchFilter(termFilter("field", "match")))).get();
|
||||
|
||||
assertHitCount(searchResponse, 3l);
|
||||
|
||||
for (SearchHit hit : searchResponse.getHits().getHits()) {
|
||||
if ("index1".equals(hit.index())) {
|
||||
assertThat(hit, hasId("1"));
|
||||
} else if ("index2".equals(hit.index())) {
|
||||
assertThat(hit, hasId("10"));
|
||||
} else if ("index3".equals(hit.index())) {
|
||||
assertThat(hit, hasId("100"));
|
||||
} else {
|
||||
fail("Returned documents should belong to either index1, index2 or index3");
|
||||
}
|
||||
}
|
||||
|
||||
//only one index specified, which is missing
|
||||
searchResponse = client().prepareSearch().setQuery(
|
||||
filteredQuery(matchAllQuery(),
|
||||
indicesFilter(termFilter("field", "missing"), "test1")
|
||||
.noMatchFilter(termFilter("field", "match")))).get();
|
||||
|
||||
assertHitCount(searchResponse, 3l);
|
||||
|
||||
for (SearchHit hit : searchResponse.getHits().getHits()) {
|
||||
if ("index1".equals(hit.index())) {
|
||||
assertThat(hit, hasId("1"));
|
||||
} else if ("index2".equals(hit.index())) {
|
||||
assertThat(hit, hasId("10"));
|
||||
} else if ("index3".equals(hit.index())) {
|
||||
assertThat(hit, hasId("100"));
|
||||
} else {
|
||||
fail("Returned documents should belong to either index1, index2 or index3");
|
||||
}
|
||||
}
|
||||
|
||||
//more than one index specified, one of them is missing
|
||||
searchResponse = client().prepareSearch().setQuery(
|
||||
filteredQuery(matchAllQuery(),
|
||||
indicesFilter(termFilter("field", "missing"), "index1", "test1")
|
||||
.noMatchFilter(termFilter("field", "match")))).get();
|
||||
|
||||
assertHitCount(searchResponse, 2l);
|
||||
|
||||
for (SearchHit hit : searchResponse.getHits().getHits()) {
|
||||
if ("index2".equals(hit.index())) {
|
||||
assertThat(hit, hasId("10"));
|
||||
} else if ("index3".equals(hit.index())) {
|
||||
assertThat(hit, hasId("100"));
|
||||
} else {
|
||||
fail("Returned documents should belong to either index2 or index3");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMinScore() {
|
||||
createIndex("test");
|
||||
|
|
Loading…
Reference in New Issue