Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Special case the _index field in queries #12027

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -22,10 +22,13 @@
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexOptions;
import org.apache.lucene.search.Query;
import org.apache.lucene.util.BytesRef;
import org.elasticsearch.Version;
import org.elasticsearch.common.Nullable;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.lucene.Lucene;
import org.elasticsearch.common.lucene.search.Queries;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.fielddata.FieldDataType;
Expand All @@ -34,9 +37,10 @@
import org.elasticsearch.index.mapper.MapperParsingException;
import org.elasticsearch.index.mapper.MergeMappingException;
import org.elasticsearch.index.mapper.MergeResult;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.MetadataFieldMapper;
import org.elasticsearch.index.mapper.ParseContext;
import org.elasticsearch.index.mapper.core.AbstractFieldMapper;
import org.elasticsearch.index.query.QueryParseContext;

import java.io.IOException;
import java.util.Iterator;
Expand Down Expand Up @@ -135,6 +139,62 @@ public String typeName() {
return CONTENT_TYPE;
}

@Override
public boolean useTermQueryWithQueryString() {
// As we spoof the presence of an indexed field we have to override
// the default of returning false which otherwise leads MatchQuery
// et al to run an analyzer over the query string and then try to
// hit the search index. We need them to use our termQuery(..)
// method which checks index names
return true;
}

/**
* This termQuery impl looks at the context to determine the index that
* is being queried and then returns a MATCH_ALL_QUERY or MATCH_NO_QUERY
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MATCH_NO_DOCS_QUERY?

* if the value matches this index. This can be useful if aliases or
* wildcards are used but the aim is to restrict the query to specific
* indices
*/
@Override
public Query termQuery(Object value, @Nullable QueryParseContext context) {
if (context == null) {
return super.termQuery(value, context);
}
if (isSameIndex(value, context.index().getName())) {
return Queries.newMatchAllQuery();
} else {
return Queries.newMatchNoDocsQuery();
}
}



@Override
public Query termsQuery(List values, QueryParseContext context) {
if (context == null) {
return super.termsQuery(values, context);
}
for (Object value : values) {
if (isSameIndex(value, context.index().getName())) {
// No need to OR these clauses - we can only logically be
// running in the context of just one of these index names.
return Queries.newMatchAllQuery();
}
}
// None of the listed index names are this one
return Queries.newMatchNoDocsQuery();
}

private boolean isSameIndex(Object value, String indexName) {
if (value instanceof BytesRef) {
BytesRef indexNameRef = new BytesRef(indexName);
return (indexNameRef.bytesEquals((BytesRef) value));
} else {
return indexName.equals(value.toString());
}
}

@Override
public String value(Object value) {
if (value == null) {
Expand Down
Expand Up @@ -699,6 +699,58 @@ private void idsQueryTests(String index) throws Exception {
assertSearchHits(searchResponse, "1", "3");
}

@Test
public void term_indexQueryTestsIndexed() throws Exception {
term_indexQueryTests("not_analyzed");
}

@Test
public void term_indexQueryTestsNotIndexed() throws Exception {
term_indexQueryTests("no");
}

private void term_indexQueryTests(String index) throws Exception {
Settings indexSettings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, Version.V_1_4_2.id).build();
String[] indexNames = { "test1", "test2" };
for (String indexName : indexNames) {
assertAcked(client()
.admin()
.indices()
.prepareCreate(indexName)
.setSettings(indexSettings)
.addMapping(
"type1",
jsonBuilder().startObject().startObject("type1").startObject("_index").field("index", index).endObject()
.endObject().endObject()));

indexRandom(true, client().prepareIndex(indexName, "type1", indexName + "1").setSource("field1", "value1"));

}
for (String indexName : indexNames) {
SearchResponse request = client().prepareSearch().setQuery(constantScoreQuery(termQuery("_index", indexName))).get();
SearchResponse searchResponse = assertSearchResponse(request);
assertHitCount(searchResponse, 1l);
assertSearchHits(searchResponse, indexName + "1");
}
for (String indexName : indexNames) {
SearchResponse request = client().prepareSearch().setQuery(constantScoreQuery(termsQuery("_index", indexName))).get();
SearchResponse searchResponse = assertSearchResponse(request);
assertHitCount(searchResponse, 1l);
assertSearchHits(searchResponse, indexName + "1");
}
for (String indexName : indexNames) {
SearchResponse request = client().prepareSearch().setQuery(constantScoreQuery(matchQuery("_index", indexName))).get();
SearchResponse searchResponse = assertSearchResponse(request);
assertHitCount(searchResponse, 1l);
assertSearchHits(searchResponse, indexName + "1");
}
{
SearchResponse request = client().prepareSearch().setQuery(constantScoreQuery(termsQuery("_index", indexNames))).get();
SearchResponse searchResponse = assertSearchResponse(request);
assertHitCount(searchResponse, indexNames.length);
}
}

@Test
public void testLimitFilter() throws Exception {
assertAcked(client().admin().indices().prepareCreate("test").setSettings(SETTING_NUMBER_OF_SHARDS, 1));
Expand Down