Skip to content

Commit 21a810f

Browse files
committed
Dualing queries
1 parent 7173f5b commit 21a810f

File tree

2 files changed

+99
-3
lines changed

2 files changed

+99
-3
lines changed

x-pack/plugin/runtime-fields/src/main/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptBooleanMappedFieldType.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,17 @@ protected String runtimeType() {
4242

4343
@Override
4444
public Object valueForDisplay(Object value) {
45-
throw new UnsupportedOperationException();
45+
if (value == null) {
46+
return null;
47+
}
48+
switch (value.toString()) {
49+
case "F":
50+
return false;
51+
case "T":
52+
return true;
53+
default:
54+
throw new IllegalArgumentException("Expected [T] or [F] but got [" + value + "]");
55+
}
4656
}
4757

4858
@Override
@@ -145,7 +155,7 @@ public Query termQuery(Object value, QueryShardContext context) {
145155
@Override
146156
public Query termsQuery(List<?> values, QueryShardContext context) {
147157
if (values.isEmpty()) {
148-
return Queries.newMatchAllQuery();
158+
return Queries.newMatchNoDocsQuery("Empty terms query");
149159
}
150160
boolean trueAllowed = false;
151161
boolean falseAllowed = false;

x-pack/plugin/runtime-fields/src/test/java/org/elasticsearch/xpack/runtimefields/mapper/ScriptBooleanMappedFieldTypeTests.java

Lines changed: 87 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import org.apache.lucene.search.LeafCollector;
1717
import org.apache.lucene.search.MatchAllDocsQuery;
1818
import org.apache.lucene.search.MatchNoDocsQuery;
19+
import org.apache.lucene.search.Query;
1920
import org.apache.lucene.search.Scorable;
2021
import org.apache.lucene.search.ScoreMode;
2122
import org.apache.lucene.search.Sort;
@@ -25,10 +26,19 @@
2526
import org.apache.lucene.util.BytesRef;
2627
import org.elasticsearch.ElasticsearchException;
2728
import org.elasticsearch.Version;
29+
import org.elasticsearch.common.bytes.BytesArray;
2830
import org.elasticsearch.common.lucene.search.function.ScriptScoreQuery;
2931
import org.elasticsearch.common.settings.Settings;
32+
import org.elasticsearch.common.xcontent.XContentParser.Token;
33+
import org.elasticsearch.common.xcontent.XContentType;
34+
import org.elasticsearch.common.xcontent.json.JsonXContent;
3035
import org.elasticsearch.index.fielddata.ScriptDocValues;
36+
import org.elasticsearch.index.mapper.BooleanFieldMapper;
37+
import org.elasticsearch.index.mapper.ContentPath;
3138
import org.elasticsearch.index.mapper.MappedFieldType;
39+
import org.elasticsearch.index.mapper.Mapper.BuilderContext;
40+
import org.elasticsearch.index.mapper.ParseContext;
41+
import org.elasticsearch.index.mapper.SourceToParse;
3242
import org.elasticsearch.index.query.QueryShardContext;
3343
import org.elasticsearch.plugins.ScriptPlugin;
3444
import org.elasticsearch.script.ScoreScript;
@@ -39,6 +49,7 @@
3949
import org.elasticsearch.script.ScriptService;
4050
import org.elasticsearch.script.ScriptType;
4151
import org.elasticsearch.search.MultiValueMode;
52+
import org.elasticsearch.test.ESTestCase;
4253
import org.elasticsearch.xpack.runtimefields.BooleanScriptFieldScript;
4354
import org.elasticsearch.xpack.runtimefields.DoubleScriptFieldScript;
4455
import org.elasticsearch.xpack.runtimefields.RuntimeFields;
@@ -56,6 +67,8 @@
5667
import static java.util.Collections.singletonList;
5768
import static org.hamcrest.Matchers.equalTo;
5869
import static org.hamcrest.Matchers.instanceOf;
70+
import static org.mockito.Mockito.mock;
71+
import static org.mockito.Mockito.when;
5972

6073
public class ScriptBooleanMappedFieldTypeTests extends AbstractNonTextScriptMappedFieldTypeTestCase {
6174
@Override
@@ -276,7 +289,80 @@ public void testTermsQueryIsExpensive() throws IOException {
276289
checkExpensiveQuery((ft, ctx) -> ft.termsQuery(List.of(false), ctx));
277290
checkExpensiveQuery((ft, ctx) -> ft.termsQuery(List.of(false, true), ctx));
278291
// This is not an expensive query
279-
assertThat(simpleMappedFieldType().termsQuery(List.of(), mockContext()), instanceOf(MatchAllDocsQuery.class));
292+
assertThat(simpleMappedFieldType().termsQuery(List.of(), mockContext()), instanceOf(MatchNoDocsQuery.class));
293+
}
294+
295+
public void testDualingQueries() throws IOException {
296+
BooleanFieldMapper ootb = new BooleanFieldMapper.Builder("foo").build(new BuilderContext(Settings.EMPTY, new ContentPath()));
297+
try (Directory directory = newDirectory(); RandomIndexWriter iw = new RandomIndexWriter(random(), directory)) {
298+
List<Boolean> values = randomList(0, 2, ESTestCase::randomBoolean);
299+
String source = "{\"foo\": " + values + "}";
300+
ParseContext ctx = mock(ParseContext.class);
301+
when(ctx.parser()).thenReturn(createParser(JsonXContent.jsonXContent, source));
302+
ParseContext.Document doc = new ParseContext.Document();
303+
when(ctx.doc()).thenReturn(doc);
304+
when(ctx.sourceToParse()).thenReturn(new SourceToParse("test", "test", new BytesArray(source), XContentType.JSON));
305+
doc.add(new StoredField("_source", new BytesRef(source)));
306+
ctx.parser().nextToken();
307+
ctx.parser().nextToken();
308+
ctx.parser().nextToken();
309+
while (ctx.parser().nextToken() != Token.END_ARRAY) {
310+
ootb.parse(ctx);
311+
}
312+
iw.addDocument(doc);
313+
try (DirectoryReader reader = iw.getReader()) {
314+
IndexSearcher searcher = newSearcher(reader);
315+
assertSameCount(
316+
searcher,
317+
source,
318+
"*",
319+
simpleMappedFieldType().existsQuery(mockContext()),
320+
ootb.fieldType().existsQuery(mockContext())
321+
);
322+
boolean term = randomBoolean();
323+
assertSameCount(
324+
searcher,
325+
source,
326+
term,
327+
simpleMappedFieldType().termQuery(term, mockContext()),
328+
ootb.fieldType().termQuery(term, mockContext())
329+
);
330+
List<Boolean> terms = randomList(0, 3, ESTestCase::randomBoolean);
331+
assertSameCount(
332+
searcher,
333+
source,
334+
terms,
335+
simpleMappedFieldType().termsQuery(terms, mockContext()),
336+
ootb.fieldType().termsQuery(terms, mockContext())
337+
);
338+
boolean low;
339+
boolean high;
340+
if (randomBoolean()) {
341+
low = high = randomBoolean();
342+
} else {
343+
low = false;
344+
high = true;
345+
}
346+
boolean includeLow = randomBoolean();
347+
boolean includeHigh = randomBoolean();
348+
assertSameCount(
349+
searcher,
350+
source,
351+
(includeLow ? "[" : "(") + low + "," + high + (includeHigh ? "]" : ")"),
352+
simpleMappedFieldType().rangeQuery(low, high, includeLow, includeHigh, null, null, null, mockContext()),
353+
ootb.fieldType().rangeQuery(low, high, includeLow, includeHigh, null, null, null, mockContext())
354+
);
355+
}
356+
}
357+
}
358+
359+
private void assertSameCount(IndexSearcher searcher, String source, Object queryDescription, Query scriptedQuery, Query ootbQuery)
360+
throws IOException {
361+
assertThat(
362+
"source=" + source + ",query=" + queryDescription + ",scripted=" + scriptedQuery + ",ootb=" + ootbQuery,
363+
searcher.count(scriptedQuery),
364+
equalTo(searcher.count(ootbQuery))
365+
);
280366
}
281367

282368
@Override

0 commit comments

Comments
 (0)