Skip to content

Commit 3f348aa

Browse files
committed
Phrase query that uses random field from docs
1 parent 3264d9e commit 3f348aa

File tree

3 files changed

+92
-3
lines changed

3 files changed

+92
-3
lines changed

test/framework/src/main/java/org/elasticsearch/datageneration/matchers/source/SourceTransforms.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import java.util.function.Function;
1919
import java.util.stream.Collectors;
2020

21-
class SourceTransforms {
21+
public class SourceTransforms {
2222
/**
2323
* This preprocessing step makes it easier to match the document using a unified structure.
2424
* It performs following modifications:

x-pack/plugin/logsdb/src/javaRestTest/java/org/elasticsearch/xpack/logsdb/qa/DataGenerationHelper.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.elasticsearch.xpack.spatial.datageneration.ShapeDataSourceHandler;
2727

2828
import java.io.IOException;
29+
import java.util.ArrayList;
2930
import java.util.Arrays;
3031
import java.util.List;
3132
import java.util.Map;
@@ -142,4 +143,17 @@ void generateDocument(XContentBuilder document, Map<String, Object> additionalFi
142143

143144
document.map(generated);
144145
}
146+
147+
List<Boolean> isNested(String[] path) {
148+
List<Boolean> result = new ArrayList<>();
149+
Map<String, Template.Entry> children = template.template();
150+
for (int i = 0; i < path.length - 1; i++) {
151+
var field = path[i];
152+
var object = (Template.Object) children.get(field);
153+
result.add(object.nested());
154+
children = object.children();
155+
}
156+
assert children.get(path[path.length - 1]) instanceof Template.Leaf;
157+
return result;
158+
}
145159
}

x-pack/plugin/logsdb/src/javaRestTest/java/org/elasticsearch/xpack/logsdb/qa/StandardVersusLogsIndexModeChallengeRestIT.java

Lines changed: 77 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,23 @@
77

88
package org.elasticsearch.xpack.logsdb.qa;
99

10+
import org.apache.lucene.search.join.ScoreMode;
1011
import org.elasticsearch.client.Request;
1112
import org.elasticsearch.client.Response;
1213
import org.elasticsearch.client.ResponseException;
1314
import org.elasticsearch.client.RestClient;
15+
import org.elasticsearch.common.Strings;
1416
import org.elasticsearch.common.settings.Settings;
1517
import org.elasticsearch.common.time.DateFormatter;
1618
import org.elasticsearch.common.time.FormatNames;
1719
import org.elasticsearch.common.xcontent.XContentHelper;
1820
import org.elasticsearch.datageneration.matchers.MatchResult;
1921
import org.elasticsearch.datageneration.matchers.Matcher;
22+
import org.elasticsearch.datageneration.matchers.source.SourceTransforms;
23+
import org.elasticsearch.index.query.MatchPhraseQueryBuilder;
24+
import org.elasticsearch.index.query.QueryBuilder;
2025
import org.elasticsearch.index.query.QueryBuilders;
26+
import org.elasticsearch.index.similarity.ScriptedSimilarity;
2127
import org.elasticsearch.search.aggregations.AggregationBuilders;
2228
import org.elasticsearch.search.aggregations.bucket.histogram.DateHistogramInterval;
2329
import org.elasticsearch.search.aggregations.bucket.histogram.HistogramAggregationBuilder;
@@ -34,6 +40,7 @@
3440
import java.time.ZonedDateTime;
3541
import java.time.temporal.ChronoUnit;
3642
import java.util.ArrayList;
43+
import java.util.Arrays;
3744
import java.util.Comparator;
3845
import java.util.List;
3946
import java.util.Map;
@@ -138,13 +145,81 @@ public void testMatchAllQuery() throws IOException {
138145
assertTrue(matchResult.getMessage(), matchResult.isMatch());
139146
}
140147

141-
public void testTermsQuery() throws IOException {
148+
private List<String> getFieldsOfType(String type, Map<String, Map<String, Object>> mappingLookup) {
149+
return mappingLookup.entrySet().stream()
150+
.filter(e -> {
151+
var mapping = e.getValue();
152+
return mapping != null && type.equals(mapping.get("type"));
153+
})
154+
.map(Map.Entry::getKey)
155+
.toList();
156+
}
157+
158+
private List<String> getSearchableFields(String type, Map<String, Map<String, Object>> mappingLookup) {
159+
var fields = new ArrayList<String>();
160+
for (var e : mappingLookup.entrySet()) {
161+
var mapping = e.getValue();
162+
if (mapping != null && type.equals(mapping.get("type"))) {
163+
boolean isIndexed = "false".equals(mapping.get("index")) == false;
164+
boolean hasDocValues = "false".equals(mapping.get("doc_values")) == false;
165+
if (isIndexed || hasDocValues) {
166+
fields.add(e.getKey());
167+
}
168+
}
169+
}
170+
return fields;
171+
}
172+
173+
private QueryBuilder nestedPhraseQuery(String path, String phrase) {
174+
String[] parts = path.split("\\.");
175+
List<Boolean> nested = dataGenerationHelper.isNested(parts);
176+
177+
QueryBuilder query = QueryBuilders.matchPhraseQuery(path, phrase);
178+
for (int i = parts.length - 2; i >= 0; i--) {
179+
if (nested.get(i)) {
180+
var pathToObject = String.join(".", Arrays.copyOfRange(parts, 0, i + 1));
181+
query = QueryBuilders.nestedQuery(pathToObject, query, ScoreMode.Max);
182+
}
183+
}
184+
return query;
185+
}
186+
187+
public void testPhraseQuery() throws IOException {
142188
int numberOfDocuments = ESTestCase.randomIntBetween(20, 80);
143189
final List<XContentBuilder> documents = generateDocuments(numberOfDocuments);
144190

191+
var mappingLookup = dataGenerationHelper.mapping().lookup();
192+
var fieldsOfType = getSearchableFields("keyword", mappingLookup);
193+
194+
if (fieldsOfType.isEmpty()) {
195+
return;
196+
}
197+
198+
var field = randomFrom(fieldsOfType);
199+
200+
XContentBuilder doc = randomFrom(documents);
201+
final Map<String, Object> document = XContentHelper.convertToMap(XContentType.JSON.xContent(), Strings.toString(doc), true);
202+
var normalized = SourceTransforms.normalize(document, mappingLookup);
203+
List<Object> values = normalized.get(field);
204+
if (values == null || values.isEmpty()) {
205+
return;
206+
}
207+
String needle = (String) randomFrom(values);
208+
var tokens = Arrays.asList(needle.split("[^a-zA-Z0-9]"));
209+
210+
if (tokens.isEmpty()) {
211+
return;
212+
}
213+
214+
int low = ESTestCase.randomIntBetween(0, tokens.size() - 1);
215+
int hi = ESTestCase.randomIntBetween(low+1, tokens.size());
216+
var phrase = String.join(" ", tokens.subList(low, hi));
217+
System.out.println("phrase: " + phrase);
218+
145219
indexDocuments(documents);
146220

147-
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(QueryBuilders.termQuery("method", "put"))
221+
QueryBuilder queryBuilder = nestedPhraseQuery(field, phrase);
222+
final SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder().query(queryBuilder)
148223
.size(numberOfDocuments);
149224

150225
final MatchResult matchResult = Matcher.matchSource()

0 commit comments

Comments
 (0)