Skip to content

Commit 3dde80a

Browse files
committed
Improve execution of terms queries over wildcard fields
1 parent 3f1e1b3 commit 3dde80a

File tree

7 files changed

+570
-230
lines changed

7 files changed

+570
-230
lines changed

x-pack/plugin/wildcard/build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
apply plugin: 'elasticsearch.internal-es-plugin'
99
apply plugin: 'elasticsearch.internal-yaml-rest-test'
10+
apply plugin: 'elasticsearch.internal-cluster-test'
1011

1112
esplugin {
1213
name = 'wildcard'
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
/*
2+
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
3+
* or more contributor license agreements. Licensed under the Elastic License
4+
* 2.0; you may not use this file except in compliance with the Elastic License
5+
* 2.0.
6+
*/
7+
8+
package org.elasticsearch.xpack.wildcard.search;
9+
10+
import org.elasticsearch.action.bulk.BulkRequestBuilder;
11+
import org.elasticsearch.action.index.IndexRequest;
12+
import org.elasticsearch.index.query.TermQueryBuilder;
13+
import org.elasticsearch.index.query.TermsQueryBuilder;
14+
import org.elasticsearch.plugins.Plugin;
15+
import org.elasticsearch.test.ESIntegTestCase;
16+
import org.elasticsearch.xcontent.XContentBuilder;
17+
import org.elasticsearch.xcontent.XContentFactory;
18+
import org.elasticsearch.xcontent.XContentType;
19+
import org.elasticsearch.xpack.wildcard.Wildcard;
20+
import org.hamcrest.Matchers;
21+
import org.junit.Before;
22+
23+
import java.io.IOException;
24+
import java.util.ArrayList;
25+
import java.util.Arrays;
26+
import java.util.Collection;
27+
import java.util.Collections;
28+
import java.util.List;
29+
30+
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertResponse;
31+
32+
public class WildcardSearchIT extends ESIntegTestCase {
33+
34+
private List<String> terms = null;
35+
36+
@Override
37+
protected Collection<Class<? extends Plugin>> nodePlugins() {
38+
return Collections.singleton(Wildcard.class);
39+
}
40+
41+
@Before
42+
public void setup() throws IOException {
43+
terms = new ArrayList<>();
44+
XContentBuilder xcb = XContentFactory.jsonBuilder()
45+
.startObject()
46+
.startObject("properties")
47+
.startObject("wildcard")
48+
.field("type", "wildcard")
49+
.endObject()
50+
.startObject("keyword")
51+
.field("type", "keyword")
52+
.endObject()
53+
.endObject()
54+
.endObject();
55+
indicesAdmin().prepareCreate("test").setMapping(xcb).get();
56+
final int numDocs = randomIntBetween(100, 1000);
57+
final BulkRequestBuilder builder = client().prepareBulk();
58+
for (int i = 0; i < numDocs; i++) {
59+
if (rarely()) {
60+
indexMultiValue(builder);
61+
} else {
62+
indexSingleValue(builder);
63+
}
64+
}
65+
assertFalse(builder.get().hasFailures());
66+
indicesAdmin().prepareRefresh("test").get();
67+
}
68+
69+
private void indexSingleValue(BulkRequestBuilder builder) {
70+
String term = randomIndexString();
71+
builder.add(
72+
new IndexRequest("test").source("{\"wildcard\" : \"" + term + "\", \"keyword\" : \"" + term + "\"}", XContentType.JSON)
73+
);
74+
terms.add(term);
75+
}
76+
77+
private void indexMultiValue(BulkRequestBuilder builder) {
78+
int docSize = randomIntBetween(1, 10);
79+
String[] docTerms = new String[docSize];
80+
for (int i = 0; i < docSize; i++) {
81+
String term = randomIndexString();
82+
terms.add(term);
83+
docTerms[i] = "\"" + term + "\"";
84+
}
85+
builder.add(
86+
new IndexRequest("test").source(
87+
"{\"wildcard\" : " + Arrays.toString(docTerms) + ", \"keyword\" : " + Arrays.toString(docTerms) + "}",
88+
XContentType.JSON
89+
)
90+
);
91+
}
92+
93+
public void testTermQueryDuel() {
94+
for (int i = 0; i < 50; i++) {
95+
String term = randomQueryString(terms);
96+
TermQueryBuilder termQueryBuilder1 = new TermQueryBuilder("wildcard", term);
97+
TermQueryBuilder termQueryBuilder2 = new TermQueryBuilder("keyword", term);
98+
assertResponse(
99+
client().prepareSearch("test").setQuery(termQueryBuilder1),
100+
response -> assertResponse(
101+
client().prepareSearch("test").setQuery(termQueryBuilder2),
102+
response2 -> assertThat(
103+
response.getHits().getTotalHits().value(),
104+
Matchers.equalTo(response2.getHits().getTotalHits().value())
105+
)
106+
)
107+
);
108+
}
109+
}
110+
111+
public void testTermsQueryDuel() {
112+
for (int i = 0; i < 10; i++) {
113+
String[] terms = new String[randomIntBetween(2, 8192)];
114+
for (int j = 0; j < terms.length; j++) {
115+
terms[j] = randomQueryString(this.terms);
116+
}
117+
TermsQueryBuilder termsQueryBuilder1 = new TermsQueryBuilder("wildcard", terms);
118+
TermsQueryBuilder termsQueryBuilder2 = new TermsQueryBuilder("keyword", terms);
119+
assertResponse(
120+
client().prepareSearch("test").setQuery(termsQueryBuilder1),
121+
response -> assertResponse(
122+
client().prepareSearch("test").setQuery(termsQueryBuilder2),
123+
response2 -> assertThat(
124+
response.getHits().getTotalHits().value(),
125+
Matchers.equalTo(response2.getHits().getTotalHits().value())
126+
)
127+
)
128+
);
129+
}
130+
}
131+
132+
private static String randomIndexString() {
133+
String string = randomAlphaOfLength(randomIntBetween(0, 30));
134+
if (rarely()) {
135+
return string + "*";
136+
} else if (rarely()) {
137+
return "*" + string;
138+
} else if (rarely()) {
139+
return "*" + string + "*";
140+
} else {
141+
return string;
142+
}
143+
}
144+
145+
private static String randomQueryString(List<String> terms) {
146+
if (rarely()) {
147+
return terms.get(randomIntBetween(0, terms.size() - 1));
148+
} else if (randomBoolean()) {
149+
return randomAlphaOfLength(randomIntBetween(0, 30));
150+
} else {
151+
return randomAlphaOfLength(1) + "*";
152+
}
153+
}
154+
}

x-pack/plugin/wildcard/src/main/java/org/elasticsearch/xpack/wildcard/mapper/BinaryDvConfirmedAutomatonQuery.java

Lines changed: 0 additions & 164 deletions
This file was deleted.

0 commit comments

Comments
 (0)