[TEST] Kill remaining lang-groovy messy tests

After #13834 many tests that used Groovy scripts (for good or bad reason) in their tests have been moved in the lang-groovy module and the issue #13837 has been created to track these messy tests in order to clean them up.

The work started with #19280, #19302 and #19336 and this PR moves the remaining messy tests back in core, removes the dependency on Groovy, changes the scripts in order to use the mocked script engine, and change the tests to integration tests.

It also moves IndexLookupIT test back (even if it has good chance to be removed soon) and fixes its tests.

It also changes AbstractQueryTestCase to use custom script plugins in tests.

closes #13837
This commit is contained in:
Tanguy Leroux 2016-07-27 14:28:12 +02:00
parent a4cb63b98c
commit 386902903e
34 changed files with 2546 additions and 1486 deletions

View File

@ -1084,13 +1084,6 @@
<suppress files="modules[/\\]lang-expression[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]expression[/\\]MoreExpressionTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]groovy[/\\]GroovyPlugin.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]groovy[/\\]GroovyScriptEngineService.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]IPv4RangeTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]IndexLookupTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]RandomScoreFunctionTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]ScriptedMetricTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]SearchFieldsTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]SimpleSortTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]messy[/\\]tests[/\\]package-info.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]groovy[/\\]GroovyScriptTests.java" checks="LineLength" />
<suppress files="modules[/\\]lang-groovy[/\\]src[/\\]test[/\\]java[/\\]org[/\\]elasticsearch[/\\]script[/\\]groovy[/\\]GroovySecurityTests.java" checks="LineLength" />
<suppress files="modules[/\\]percolator[/\\]src[/\\]main[/\\]java[/\\]org[/\\]elasticsearch[/\\]percolator[/\\]MultiPercolateRequest.java" checks="LineLength" />

View File

@ -34,7 +34,6 @@ import org.elasticsearch.cluster.ClusterStateListener;
import org.elasticsearch.cluster.metadata.MetaData;
import org.elasticsearch.cluster.service.ClusterService;
import org.elasticsearch.common.ParseField;
import org.elasticsearch.common.ParseFieldMatcher;
import org.elasticsearch.common.Strings;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.cache.Cache;
@ -101,7 +100,6 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
private final ScriptModes scriptModes;
private final ScriptContextRegistry scriptContextRegistry;
private final ParseFieldMatcher parseFieldMatcher;
private final ScriptMetrics scriptMetrics = new ScriptMetrics();
private ClusterState clusterState;
@ -113,7 +111,6 @@ public class ScriptService extends AbstractComponent implements Closeable, Clust
Objects.requireNonNull(scriptEngineRegistry);
Objects.requireNonNull(scriptContextRegistry);
Objects.requireNonNull(scriptSettings);
this.parseFieldMatcher = new ParseFieldMatcher(settings);
if (Strings.hasLength(settings.get(DISABLE_DYNAMIC_SCRIPTING_SETTING))) {
throw new IllegalArgumentException(DISABLE_DYNAMIC_SCRIPTING_SETTING + " is not a supported setting, replace with fine-grained script settings. \n" +
"Dynamic scripts can be enabled for all languages and all operations by replacing `script.disable_dynamic: false` with `script.inline: true` and `script.stored: true` in elasticsearch.yml");

View File

@ -19,11 +19,9 @@
package org.elasticsearch.script;
import org.elasticsearch.common.collect.Tuple;
import org.elasticsearch.common.settings.Setting;
import org.elasticsearch.common.settings.Setting.Property;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.script.ScriptService;
import java.util.ArrayList;
import java.util.Collections;
@ -31,7 +29,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
public class ScriptSettings {

View File

@ -34,7 +34,7 @@ import static org.hamcrest.Matchers.instanceOf;
public class ScriptQueryBuilderTests extends AbstractQueryTestCase<ScriptQueryBuilder> {
@Override
protected ScriptQueryBuilder doCreateTestQueryBuilder() {
String script = "5";
String script = "1";
Map<String, Object> params = Collections.emptyMap();
return new ScriptQueryBuilder(new Script(script, ScriptType.INLINE, MockScriptEngine.NAME, params));
}

View File

@ -155,7 +155,7 @@ public class FunctionScoreQueryBuilderTests extends AbstractQueryTestCase<Functi
functionBuilder = fieldValueFactorFunctionBuilder;
break;
case 2:
String script = "5";
String script = "1";
Map<String, Object> params = Collections.emptyMap();
functionBuilder = new ScriptScoreFunctionBuilder(
new Script(script, ScriptService.ScriptType.INLINE, MockScriptEngine.NAME, params));

View File

@ -37,14 +37,16 @@ public class FileScriptTests extends ESTestCase {
Path scriptsDir = homeDir.resolve("config").resolve("scripts");
Files.createDirectories(scriptsDir);
Path mockscript = scriptsDir.resolve("script1.mockscript");
Files.write(mockscript, "1".getBytes("UTF-8"));
String scriptSource = "1";
Files.write(mockscript, scriptSource.getBytes("UTF-8"));
settings = Settings.builder()
.put(Environment.PATH_HOME_SETTING.getKey(), homeDir)
// no file watching, so we don't need a ResourceWatcherService
.put(ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING.getKey(), false)
.put(settings)
.build();
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections.singleton(new MockScriptEngine()));
MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap(scriptSource, script -> "1"));
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections.singleton(scriptEngine));
ScriptContextRegistry scriptContextRegistry = new ScriptContextRegistry(Collections.emptyList());
ScriptSettings scriptSettings = new ScriptSettings(scriptEngineRegistry, scriptContextRegistry);
return new ScriptService(settings, new Environment(settings), null, scriptEngineRegistry, scriptContextRegistry, scriptSettings);

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,9 @@ public class ScriptContextTests extends ESTestCase {
.put("script." + PLUGIN_NAME + "_custom_globally_disabled_op", "false")
.put("script.engine." + MockScriptEngine.NAME + ".inline." + PLUGIN_NAME + "_custom_exp_disabled_op", "false")
.build();
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections.singletonList(new MockScriptEngine()));
MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", script -> "1"));
ScriptEngineRegistry scriptEngineRegistry = new ScriptEngineRegistry(Collections.singletonList(scriptEngine));
List<ScriptContext.Plugin> customContexts = Arrays.asList(
new ScriptContext.Plugin(PLUGIN_NAME, "custom_op"),
new ScriptContext.Plugin(PLUGIN_NAME, "custom_exp_disabled_op"),

View File

@ -86,7 +86,7 @@ public class StoredScriptsIT extends ESIntegTestCase {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
return Collections.emptyMap();
return Collections.singletonMap("1", script -> "1");
}
}
}

View File

@ -16,13 +16,14 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.messy.tests;
package org.elasticsearch.search.aggregations.bucket;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.search.aggregations.AggregationTestScriptsPlugin;
import org.elasticsearch.search.aggregations.Aggregator.SubAggCollectionMode;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
import org.elasticsearch.search.aggregations.bucket.range.Range;
@ -36,12 +37,15 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.script.ScriptService.ScriptType;
import static org.elasticsearch.search.aggregations.AggregationBuilders.histogram;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.range;
import static org.elasticsearch.search.aggregations.AggregationBuilders.sum;
import static org.elasticsearch.search.aggregations.AggregationBuilders.terms;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
@ -49,11 +53,8 @@ import static org.hamcrest.Matchers.is;
import static org.hamcrest.core.IsNull.notNullValue;
import static org.hamcrest.core.IsNull.nullValue;
/**
*
*/
@ESIntegTestCase.SuiteScopeTestCase
public class RangeTests extends ESIntegTestCase {
public class RangeIT extends ESIntegTestCase {
private static final String SINGLE_VALUED_FIELD_NAME = "l_value";
private static final String MULTI_VALUED_FIELD_NAME = "l_values";
@ -62,7 +63,30 @@ public class RangeTests extends ESIntegTestCase {
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class);
return Collections.singleton(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends AggregationTestScriptsPlugin {
@Override
@SuppressWarnings("unchecked")
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = super.pluginScripts();
scripts.put("doc['" + SINGLE_VALUED_FIELD_NAME + "'].value", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Longs value = (ScriptDocValues.Longs) doc.get(SINGLE_VALUED_FIELD_NAME);
return value.getValue();
});
scripts.put("doc['" + MULTI_VALUED_FIELD_NAME + "'].values", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Longs value = (ScriptDocValues.Longs) doc.get(MULTI_VALUED_FIELD_NAME);
return value.getValues();
});
return scripts;
}
}
@Override
@ -94,10 +118,10 @@ public class RangeTests extends ESIntegTestCase {
SearchResponse response = client().prepareSearch("idx")
.addAggregation(terms("terms").field(MULTI_VALUED_FIELD_NAME).size(100)
.collectMode(randomFrom(SubAggCollectionMode.values())).subAggregation(
range("range").field(SINGLE_VALUED_FIELD_NAME)
.addUnboundedTo(3)
.addRange(3, 6)
.addUnboundedFrom(6)))
range("range").field(SINGLE_VALUED_FIELD_NAME)
.addUnboundedTo(3)
.addRange(3, 6)
.addUnboundedFrom(6)))
.execute().actionGet();
assertSearchResponse(response);
@ -112,7 +136,7 @@ public class RangeTests extends ESIntegTestCase {
Range range = bucket.getAggregations().get("range");
List<? extends Bucket> buckets = range.getBuckets();
Range.Bucket rangeBucket = buckets.get(0);
assertThat((String) rangeBucket.getKey(), equalTo("*-3.0"));
assertThat(rangeBucket.getKey(), equalTo("*-3.0"));
assertThat(rangeBucket.getKeyAsString(), equalTo("*-3.0"));
assertThat(rangeBucket, notNullValue());
assertThat(rangeBucket.getFromAsString(), nullValue());
@ -125,7 +149,7 @@ public class RangeTests extends ESIntegTestCase {
assertThat(rangeBucket.getDocCount(), equalTo(0L));
}
rangeBucket = buckets.get(1);
assertThat((String) rangeBucket.getKey(), equalTo("3.0-6.0"));
assertThat(rangeBucket.getKey(), equalTo("3.0-6.0"));
assertThat(rangeBucket.getKeyAsString(), equalTo("3.0-6.0"));
assertThat(rangeBucket, notNullValue());
assertThat(rangeBucket.getFromAsString(), equalTo("3.0"));
@ -138,7 +162,7 @@ public class RangeTests extends ESIntegTestCase {
assertThat(rangeBucket.getDocCount(), equalTo(0L));
}
rangeBucket = buckets.get(2);
assertThat((String) rangeBucket.getKey(), equalTo("6.0-*"));
assertThat(rangeBucket.getKey(), equalTo("6.0-*"));
assertThat(rangeBucket.getKeyAsString(), equalTo("6.0-*"));
assertThat(rangeBucket, notNullValue());
assertThat(rangeBucket.getFromAsString(), equalTo("6.0"));
@ -173,7 +197,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3.0"));
assertThat(bucket.getKey(), equalTo("*-3.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -182,7 +206,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -191,7 +215,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6.0-*"));
assertThat(bucket.getKey(), equalTo("6.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -217,7 +241,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3"));
assertThat(bucket.getKey(), equalTo("*-3"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -226,7 +250,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3-6"));
assertThat(bucket.getKey(), equalTo("3-6"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3"));
@ -235,7 +259,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6-*"));
assertThat(bucket.getKey(), equalTo("6-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6"));
@ -263,7 +287,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("r1"));
assertThat(bucket.getKey(), equalTo("r1"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -272,7 +296,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("r2"));
assertThat(bucket.getKey(), equalTo("r2"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -281,7 +305,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("r3"));
assertThat(bucket.getKey(), equalTo("r3"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -313,7 +337,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3.0"));
assertThat(bucket.getKey(), equalTo("*-3.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -322,13 +346,13 @@ public class RangeTests extends ESIntegTestCase {
Sum sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo(3.0)); // 1 + 2
assertThat((String) propertiesKeys[0], equalTo("*-3.0"));
assertThat((long) propertiesDocCounts[0], equalTo(2L));
assertThat((double) propertiesCounts[0], equalTo(3.0));
assertThat(propertiesKeys[0], equalTo("*-3.0"));
assertThat(propertiesDocCounts[0], equalTo(2L));
assertThat(propertiesCounts[0], equalTo(3.0));
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -337,13 +361,13 @@ public class RangeTests extends ESIntegTestCase {
sum = bucket.getAggregations().get("sum");
assertThat(sum, notNullValue());
assertThat(sum.getValue(), equalTo(12.0)); // 3 + 4 + 5
assertThat((String) propertiesKeys[1], equalTo("3.0-6.0"));
assertThat((long) propertiesDocCounts[1], equalTo(3L));
assertThat((double) propertiesCounts[1], equalTo(12.0));
assertThat(propertiesKeys[1], equalTo("3.0-6.0"));
assertThat(propertiesDocCounts[1], equalTo(3L));
assertThat(propertiesCounts[1], equalTo(12.0));
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6.0-*"));
assertThat(bucket.getKey(), equalTo("6.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -356,17 +380,22 @@ public class RangeTests extends ESIntegTestCase {
total += i + 1;
}
assertThat(sum.getValue(), equalTo((double) total));
assertThat((String) propertiesKeys[2], equalTo("6.0-*"));
assertThat((long) propertiesDocCounts[2], equalTo(numDocs - 5L));
assertThat((double) propertiesCounts[2], equalTo((double) total));
assertThat(propertiesKeys[2], equalTo("6.0-*"));
assertThat(propertiesDocCounts[2], equalTo(numDocs - 5L));
assertThat(propertiesCounts[2], equalTo((double) total));
}
public void testSingleValuedFieldWithValueScript() throws Exception {
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
range("range").field(SINGLE_VALUED_FIELD_NAME).script(new Script("_value + 1")).addUnboundedTo(3).addRange(3, 6)
.addUnboundedFrom(6)).execute().actionGet();
range("range")
.field(SINGLE_VALUED_FIELD_NAME)
.script(new Script("_value + 1", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addUnboundedTo(3)
.addRange(3, 6)
.addUnboundedFrom(6))
.get();
assertSearchResponse(response);
@ -378,7 +407,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3.0"));
assertThat(bucket.getKey(), equalTo("*-3.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -387,7 +416,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -396,7 +425,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6.0-*"));
assertThat(bucket.getKey(), equalTo("6.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -437,7 +466,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3.0"));
assertThat(bucket.getKey(), equalTo("*-3.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -446,7 +475,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -455,7 +484,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6.0-*"));
assertThat(bucket.getKey(), equalTo("6.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -480,8 +509,13 @@ public class RangeTests extends ESIntegTestCase {
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
range("range").field(MULTI_VALUED_FIELD_NAME).script(new Script("_value + 1")).addUnboundedTo(3).addRange(3, 6)
.addUnboundedFrom(6)).execute().actionGet();
range("range")
.field(MULTI_VALUED_FIELD_NAME)
.script(new Script("_value + 1", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addUnboundedTo(3)
.addRange(3, 6)
.addUnboundedFrom(6))
.get();
assertSearchResponse(response);
@ -494,7 +528,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3.0"));
assertThat(bucket.getKey(), equalTo("*-3.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -503,7 +537,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -512,7 +546,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6.0-*"));
assertThat(bucket.getKey(), equalTo("6.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -538,11 +572,16 @@ public class RangeTests extends ESIntegTestCase {
*/
public void testScriptSingleValue() throws Exception {
Script script = new Script("doc['" + SINGLE_VALUED_FIELD_NAME + "'].value", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
range("range").script(new Script("doc['" + SINGLE_VALUED_FIELD_NAME + "'].value")).addUnboundedTo(3).addRange(3, 6)
.addUnboundedFrom(6)).execute().actionGet();
range("range")
.script(script)
.addUnboundedTo(3)
.addRange(3, 6)
.addUnboundedFrom(6))
.get();
assertSearchResponse(response);
@ -555,7 +594,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3.0"));
assertThat(bucket.getKey(), equalTo("*-3.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -564,7 +603,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -573,7 +612,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6.0-*"));
assertThat(bucket.getKey(), equalTo("6.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -600,7 +639,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*--1.0"));
assertThat(bucket.getKey(), equalTo("*--1.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(-1.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -609,7 +648,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("1000.0-*"));
assertThat(bucket.getKey(), equalTo("1000.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(1000d));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("1000.0"));
@ -618,11 +657,17 @@ public class RangeTests extends ESIntegTestCase {
}
public void testScriptMultiValued() throws Exception {
Script script = new Script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
range("range").script(new Script("doc['" + MULTI_VALUED_FIELD_NAME + "'].values")).addUnboundedTo(3).addRange(3, 6)
.addUnboundedFrom(6)).execute().actionGet();
range("range")
.script(script)
.addUnboundedTo(3)
.addRange(3, 6)
.addUnboundedFrom(6))
.get();
assertSearchResponse(response);
@ -635,7 +680,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3.0"));
assertThat(bucket.getKey(), equalTo("*-3.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -644,7 +689,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -653,7 +698,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6.0-*"));
assertThat(bucket.getKey(), equalTo("6.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -698,7 +743,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3.0"));
assertThat(bucket.getKey(), equalTo("*-3.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -707,7 +752,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -716,7 +761,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6.0-*"));
assertThat(bucket.getKey(), equalTo("6.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -746,7 +791,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-3.0"));
assertThat(bucket.getKey(), equalTo("*-3.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(3.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -755,7 +800,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -764,7 +809,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("6.0-*"));
assertThat(bucket.getKey(), equalTo("6.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(6.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("6.0"));
@ -793,7 +838,7 @@ public class RangeTests extends ESIntegTestCase {
Range.Bucket bucket = buckets.get(0);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("*-5.0"));
assertThat(bucket.getKey(), equalTo("*-5.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(Double.NEGATIVE_INFINITY));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(5.0));
assertThat(bucket.getFromAsString(), nullValue());
@ -802,7 +847,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(1);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("3.0-6.0"));
assertThat(bucket.getKey(), equalTo("3.0-6.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(3.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(6.0));
assertThat(bucket.getFromAsString(), equalTo("3.0"));
@ -811,7 +856,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(2);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("4.0-5.0"));
assertThat(bucket.getKey(), equalTo("4.0-5.0"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(4.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(5.0));
assertThat(bucket.getFromAsString(), equalTo("4.0"));
@ -820,7 +865,7 @@ public class RangeTests extends ESIntegTestCase {
bucket = buckets.get(3);
assertThat(bucket, notNullValue());
assertThat((String) bucket.getKey(), equalTo("4.0-*"));
assertThat(bucket.getKey(), equalTo("4.0-*"));
assertThat(((Number) bucket.getFrom()).doubleValue(), equalTo(4.0));
assertThat(((Number) bucket.getTo()).doubleValue(), equalTo(Double.POSITIVE_INFINITY));
assertThat(bucket.getFromAsString(), equalTo("4.0"));
@ -831,9 +876,16 @@ public class RangeTests extends ESIntegTestCase {
public void testEmptyAggregation() throws Exception {
SearchResponse searchResponse = client().prepareSearch("empty_bucket_idx")
.setQuery(matchAllQuery())
.addAggregation(histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(1L).minDocCount(0)
.subAggregation(range("range").field(SINGLE_VALUED_FIELD_NAME).addRange("0-2", 0.0, 2.0)))
.execute().actionGet();
.addAggregation(
histogram("histo")
.field(SINGLE_VALUED_FIELD_NAME)
.interval(1L)
.minDocCount(0)
.subAggregation(
range("range")
.field(SINGLE_VALUED_FIELD_NAME)
.addRange("0-2", 0.0, 2.0)))
.get();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(2L));
Histogram histo = searchResponse.getAggregations().get("histo");
@ -843,11 +895,11 @@ public class RangeTests extends ESIntegTestCase {
Range range = bucket.getAggregations().get("range");
// TODO: use diamond once JI-9019884 is fixed
List<Range.Bucket> buckets = new ArrayList<Range.Bucket>(range.getBuckets());
List<Range.Bucket> buckets = new ArrayList<>(range.getBuckets());
assertThat(range, Matchers.notNullValue());
assertThat(range.getName(), equalTo("range"));
assertThat(buckets.size(), is(1));
assertThat((String) buckets.get(0).getKey(), equalTo("0-2"));
assertThat(buckets.get(0).getKey(), equalTo("0-2"));
assertThat(((Number) buckets.get(0).getFrom()).doubleValue(), equalTo(0.0));
assertThat(((Number) buckets.get(0).getTo()).doubleValue(), equalTo(2.0));
assertThat(buckets.get(0).getFromAsString(), equalTo("0.0"));

View File

@ -17,18 +17,18 @@
* under the License.
*/
package org.elasticsearch.messy.tests;
package org.elasticsearch.search.aggregations.metrics;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.env.Environment;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.script.groovy.GroovyScriptEngineService;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.global.Global;
@ -39,12 +39,17 @@ import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.ESIntegTestCase.ClusterScope;
import org.elasticsearch.test.ESIntegTestCase.Scope;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
@ -64,13 +69,130 @@ import static org.hamcrest.Matchers.sameInstance;
@ClusterScope(scope = Scope.SUITE)
@ESIntegTestCase.SuiteScopeTestCase
public class ScriptedMetricTests extends ESIntegTestCase {
public class ScriptedMetricIT extends ESIntegTestCase {
private static long numDocs;
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class);
return Collections.singleton(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
@SuppressWarnings("unchecked")
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("_agg['count'] = 1", vars ->
aggScript(vars, agg -> ((Map<String, Object>) agg).put("count", 1)));
scripts.put("_agg.add(1)", vars ->
aggScript(vars, agg -> ((List) agg).add(1)));
scripts.put("vars.multiplier = 3", vars ->
((Map<String, Object>) vars.get("vars")).put("multiplier", 3));
scripts.put("_agg.add(vars.multiplier)", vars ->
aggScript(vars, agg -> ((List) agg).add(XContentMapValues.extractValue("vars.multiplier", vars))));
// Equivalent to:
//
// newaggregation = [];
// sum = 0;
//
// for (a in _agg) {
// sum += a
// };
//
// newaggregation.add(sum);
// return newaggregation"
//
scripts.put("sum agg values as a new aggregation", vars -> {
List newAggregation = new ArrayList();
List<?> agg = (List<?>) vars.get("_agg");
if (agg != null) {
Integer sum = 0;
for (Object a : (List) agg) {
sum += ((Number) a).intValue();
}
newAggregation.add(sum);
}
return newAggregation;
});
// Equivalent to:
//
// newaggregation = [];
// sum = 0;
//
// for (aggregation in _aggs) {
// for (a in aggregation) {
// sum += a
// }
// };
//
// newaggregation.add(sum);
// return newaggregation"
//
scripts.put("sum aggs of agg values as a new aggregation", vars -> {
List newAggregation = new ArrayList();
Integer sum = 0;
List<?> aggs = (List<?>) vars.get("_aggs");
for (Object aggregation : (List) aggs) {
if (aggregation != null) {
for (Object a : (List) aggregation) {
sum += ((Number) a).intValue();
}
}
}
newAggregation.add(sum);
return newAggregation;
});
// Equivalent to:
//
// newaggregation = [];
// sum = 0;
//
// for (aggregation in _aggs) {
// for (a in aggregation) {
// sum += a
// }
// };
//
// newaggregation.add(sum * multiplier);
// return newaggregation"
//
scripts.put("multiplied sum aggs of agg values as a new aggregation", vars -> {
Integer multiplier = (Integer) vars.get("multiplier");
List newAggregation = new ArrayList();
Integer sum = 0;
List<?> aggs = (List<?>) vars.get("_aggs");
for (Object aggregation : (List) aggs) {
if (aggregation != null) {
for (Object a : (List) aggregation) {
sum += ((Number) a).intValue();
}
}
}
newAggregation.add(sum * multiplier);
return newAggregation;
});
return scripts;
}
@SuppressWarnings("unchecked")
static <T> Object aggScript(Map<String, Object> vars, Consumer<T> fn) {
T agg = (T) vars.get("_agg");
fn.accept(agg);
return agg;
}
}
@Override
@ -83,7 +205,7 @@ public class ScriptedMetricTests extends ESIntegTestCase {
for (int i = 0; i < numDocs; i++) {
builders.add(client().prepareIndex("idx", "type", "" + i).setSource(
jsonBuilder().startObject().field("value", randomAsciiOfLengthBetween(5, 15))
.field("l_value", i).endObject()));
.field("l_value", i).endObject()));
}
indexRandom(true, builders);
@ -102,25 +224,28 @@ public class ScriptedMetricTests extends ESIntegTestCase {
jsonBuilder().startObject().field("value", i * 2).endObject()));
}
// When using the MockScriptPlugin we can map Stored scripts to inline scripts:
// the id of the stored script is used in test method while the source of the stored script
// must match a predefined script from CustomScriptPlugin.pluginScripts() method
assertAcked(client().admin().cluster().preparePutStoredScript()
.setScriptLang(GroovyScriptEngineService.NAME)
.setId("initScript_indexed")
.setScriptLang(CustomScriptPlugin.NAME)
.setId("initScript_stored")
.setSource(new BytesArray("{\"script\":\"vars.multiplier = 3\"}")));
assertAcked(client().admin().cluster().preparePutStoredScript()
.setScriptLang(GroovyScriptEngineService.NAME)
.setId("mapScript_indexed")
.setScriptLang(CustomScriptPlugin.NAME)
.setId("mapScript_stored")
.setSource(new BytesArray("{\"script\":\"_agg.add(vars.multiplier)\"}")));
assertAcked(client().admin().cluster().preparePutStoredScript()
.setScriptLang(GroovyScriptEngineService.NAME)
.setId("combineScript_indexed")
.setSource(new BytesArray("{\"script\":\"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation\"}")));
.setScriptLang(CustomScriptPlugin.NAME)
.setId("combineScript_stored")
.setSource(new BytesArray("{\"script\":\"sum agg values as a new aggregation\"}")));
assertAcked(client().admin().cluster().preparePutStoredScript()
.setScriptLang(GroovyScriptEngineService.NAME)
.setId("reduceScript_indexed")
.setSource(new BytesArray("{\"script\":\"newaggregation = []; sum = 0;for (agg in _aggs) { for (a in agg) { sum += a} }; newaggregation.add(sum); return newaggregation\"}")));
.setScriptLang(CustomScriptPlugin.NAME)
.setId("reduceScript_stored")
.setSource(new BytesArray("{\"script\":\"sum aggs of agg values as a new aggregation\"}")));
indexRandom(true, builders);
ensureSearchable();
@ -128,16 +253,36 @@ public class ScriptedMetricTests extends ESIntegTestCase {
@Override
protected Settings nodeSettings(int nodeOrdinal) {
Settings settings = Settings.builder()
Path config = createTempDir().resolve("config");
Path scripts = config.resolve("scripts");
try {
Files.createDirectories(scripts);
// When using the MockScriptPlugin we can map File scripts to inline scripts:
// the name of the file script is used in test method while the source of the file script
// must match a predefined script from CustomScriptPlugin.pluginScripts() method
Files.write(scripts.resolve("init_script.mockscript"), "vars.multiplier = 3".getBytes("UTF-8"));
Files.write(scripts.resolve("map_script.mockscript"), "_agg.add(vars.multiplier)".getBytes("UTF-8"));
Files.write(scripts.resolve("combine_script.mockscript"), "sum agg values as a new aggregation".getBytes("UTF-8"));
Files.write(scripts.resolve("reduce_script.mockscript"), "sum aggs of agg values as a new aggregation".getBytes("UTF-8"));
} catch (IOException e) {
throw new RuntimeException("failed to create scripts");
}
return Settings.builder()
.put(super.nodeSettings(nodeOrdinal))
.put(Environment.PATH_CONF_SETTING.getKey(), getDataPath("/org/elasticsearch/messy/tests/conf"))
.put(Environment.PATH_CONF_SETTING.getKey(), config)
.build();
return settings;
}
public void testMap() {
SearchResponse response = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(scriptedMetric("scripted").mapScript(new Script("_agg['count'] = 1"))).execute().actionGet();
Script mapScript = new Script("_agg['count'] = 1", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client().prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(scriptedMetric("scripted").mapScript(mapScript))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -159,7 +304,7 @@ public class ScriptedMetricTests extends ESIntegTestCase {
if (map.size() == 1) {
assertThat(map.get("count"), notNullValue());
assertThat(map.get("count"), instanceOf(Number.class));
assertThat((Number) map.get("count"), equalTo((Number) 1));
assertThat(map.get("count"), equalTo((Number) 1));
numShardsRun++;
}
}
@ -172,8 +317,12 @@ public class ScriptedMetricTests extends ESIntegTestCase {
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
SearchResponse response = client().prepareSearch("idx").setQuery(matchAllQuery())
.addAggregation(scriptedMetric("scripted").params(params).mapScript(new Script("_agg.add(1)"))).execute().actionGet();
Script mapScript = new Script("_agg.add(1)", ScriptType.INLINE, CustomScriptPlugin.NAME, params);
SearchResponse response = client().prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(scriptedMetric("scripted").params(params).mapScript(mapScript))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -205,6 +354,7 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testInitMapWithParams() {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
@ -213,8 +363,11 @@ public class ScriptedMetricTests extends ESIntegTestCase {
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted").params(params).initScript(new Script("vars.multiplier = 3"))
.mapScript(new Script("_agg.add(vars.multiplier)"))).execute().actionGet();
scriptedMetric("scripted")
.params(params)
.initScript(new Script("vars.multiplier = 3", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.mapScript(new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null)))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -246,20 +399,22 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testMapCombineWithParams() {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Script mapScript = new Script("_agg.add(1)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script combineScript = new Script("sum agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted")
.params(params)
.mapScript(new Script("_agg.add(1)"))
.combineScript(
new Script(
"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation")))
.mapScript(mapScript)
.combineScript(combineScript))
.execute().actionGet();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -295,22 +450,25 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testInitMapCombineWithParams() {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Script initScript = new Script("vars.multiplier = 3", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script mapScript = new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script combineScript = new Script("sum agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted")
.params(params)
.initScript(new Script("vars.multiplier = 3"))
.mapScript(new Script("_agg.add(vars.multiplier)"))
.combineScript(
new Script(
"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation")))
.execute().actionGet();
.initScript(initScript)
.mapScript(mapScript)
.combineScript(combineScript))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -345,25 +503,27 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testInitMapCombineReduceWithParams() {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Script initScript = new Script("vars.multiplier = 3", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script mapScript = new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script combineScript = new Script("sum agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script reduceScript = new Script("sum aggs of agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted")
.params(params)
.initScript(new Script("vars.multiplier = 3"))
.mapScript(new Script("_agg.add(vars.multiplier)"))
.combineScript(
new Script(
"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation"))
.reduceScript(
new Script(
"newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum); return newaggregation")))
.execute().actionGet();
.initScript(initScript)
.mapScript(mapScript)
.combineScript(combineScript)
.reduceScript(reduceScript))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -386,9 +546,16 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testInitMapCombineReduceGetProperty() throws Exception {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Script initScript = new Script("vars.multiplier = 3", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script mapScript = new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script combineScript = new Script("sum agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script reduceScript = new Script("sum aggs of agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse searchResponse = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
@ -397,15 +564,11 @@ public class ScriptedMetricTests extends ESIntegTestCase {
.subAggregation(
scriptedMetric("scripted")
.params(params)
.initScript(new Script("vars.multiplier = 3"))
.mapScript(new Script("_agg.add(vars.multiplier)"))
.combineScript(
new Script(
"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation"))
.reduceScript(
new Script(
"newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum); return newaggregation"))))
.execute().actionGet();
.initScript(initScript)
.mapScript(mapScript)
.combineScript(combineScript)
.reduceScript(reduceScript)))
.get();
assertSearchResponse(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(numDocs));
@ -437,24 +600,25 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testMapCombineReduceWithParams() {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Script mapScript = new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script combineScript = new Script("sum agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script reduceScript = new Script("sum aggs of agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted")
.params(params)
.mapScript(new Script("_agg.add(vars.multiplier)"))
.combineScript(
new Script(
"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation"))
.reduceScript(
new Script(
"newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum); return newaggregation")))
.execute().actionGet();
.mapScript(mapScript)
.combineScript(combineScript)
.reduceScript(reduceScript))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -476,22 +640,25 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testInitMapReduceWithParams() {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Script initScript = new Script("vars.multiplier = 3", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script mapScript = new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script reduceScript = new Script("sum aggs of agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted")
.params(params)
.initScript(new Script("vars.multiplier = 3"))
.mapScript(new Script("_agg.add(vars.multiplier)"))
.reduceScript(
new Script(
"newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum); return newaggregation")))
.execute().actionGet();
.initScript(initScript)
.mapScript(mapScript)
.reduceScript(reduceScript))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -517,17 +684,18 @@ public class ScriptedMetricTests extends ESIntegTestCase {
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Script mapScript = new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script reduceScript = new Script("sum aggs of agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted")
.params(params)
.mapScript(new Script("_agg.add(vars.multiplier)"))
.reduceScript(
new Script(
"newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum); return newaggregation")))
.execute().actionGet();
.mapScript(mapScript)
.reduceScript(reduceScript))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -549,27 +717,30 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testInitMapCombineReduceWithParamsAndReduceParams() {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Map<String, Object> reduceParams = new HashMap<>();
reduceParams.put("multiplier", 4);
Script initScript = new Script("vars.multiplier = 3", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script mapScript = new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script combineScript = new Script("sum agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script reduceScript = new Script("multiplied sum aggs of agg values as a new aggregation", ScriptType.INLINE,
CustomScriptPlugin.NAME, reduceParams);
SearchResponse response = client()
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted")
.params(params)
.initScript(new Script("vars.multiplier = 3"))
.mapScript(new Script("_agg.add(vars.multiplier)"))
.combineScript(
new Script(
"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation"))
.reduceScript(
new Script(
"newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum * multiplier); return newaggregation",
ScriptType.INLINE, null, reduceParams)))
.initScript(initScript)
.mapScript(mapScript)
.combineScript(combineScript)
.reduceScript(reduceScript))
.execute().actionGet();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -589,9 +760,10 @@ public class ScriptedMetricTests extends ESIntegTestCase {
assertThat(((Number) object).longValue(), equalTo(numDocs * 12));
}
public void testInitMapCombineReduceWithParamsIndexed() {
public void testInitMapCombineReduceWithParamsStored() {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
@ -600,11 +772,13 @@ public class ScriptedMetricTests extends ESIntegTestCase {
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted").params(params)
.initScript(new Script("initScript_indexed", ScriptType.STORED, null, null))
.mapScript(new Script("mapScript_indexed", ScriptType.STORED, null, null))
.combineScript(new Script("combineScript_indexed", ScriptType.STORED, null, null))
.reduceScript(new Script("reduceScript_indexed", ScriptType.STORED, null, null))).execute().actionGet();
scriptedMetric("scripted")
.params(params)
.initScript(new Script("initScript_stored", ScriptType.STORED, CustomScriptPlugin.NAME, null))
.mapScript(new Script("mapScript_stored", ScriptType.STORED, CustomScriptPlugin.NAME, null))
.combineScript(new Script("combineScript_stored", ScriptType.STORED, CustomScriptPlugin.NAME, null))
.reduceScript(new Script("reduceScript_stored", ScriptType.STORED, CustomScriptPlugin.NAME, null)))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -634,10 +808,13 @@ public class ScriptedMetricTests extends ESIntegTestCase {
.prepareSearch("idx")
.setQuery(matchAllQuery())
.addAggregation(
scriptedMetric("scripted").params(params).initScript(new Script("init_script", ScriptType.FILE, null, null))
.mapScript(new Script("map_script", ScriptType.FILE, null, null))
.combineScript(new Script("combine_script", ScriptType.FILE, null, null))
.reduceScript(new Script("reduce_script", ScriptType.FILE, null, null))).execute().actionGet();
scriptedMetric("scripted")
.params(params)
.initScript(new Script("init_script", ScriptType.FILE, CustomScriptPlugin.NAME, null))
.mapScript(new Script("map_script", ScriptType.FILE, CustomScriptPlugin.NAME, null))
.combineScript(new Script("combine_script", ScriptType.FILE, CustomScriptPlugin.NAME, null))
.reduceScript(new Script("reduce_script", ScriptType.FILE, CustomScriptPlugin.NAME, null)))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
@ -659,10 +836,16 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testInitMapCombineReduceWithParamsAsSubAgg() {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Script initScript = new Script("vars.multiplier = 3", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script mapScript = new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script combineScript = new Script("sum agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script reduceScript = new Script("sum aggs of agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse response = client()
.prepareSearch("idx")
.setQuery(matchAllQuery()).setSize(1000)
@ -673,15 +856,11 @@ public class ScriptedMetricTests extends ESIntegTestCase {
.subAggregation(
scriptedMetric("scripted")
.params(params)
.initScript(new Script("vars.multiplier = 3"))
.mapScript(new Script("_agg.add(vars.multiplier)"))
.combineScript(
new Script(
"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation"))
.reduceScript(
new Script(
"newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum); return newaggregation"))))
.execute().actionGet();
.initScript(initScript)
.mapScript(mapScript)
.combineScript(combineScript)
.reduceScript(reduceScript)))
.get();
assertSearchResponse(response);
assertThat(response.getHits().getTotalHits(), equalTo(numDocs));
Aggregation aggregation = response.getAggregations().get("histo");
@ -716,25 +895,27 @@ public class ScriptedMetricTests extends ESIntegTestCase {
public void testEmptyAggregation() throws Exception {
Map<String, Object> varsMap = new HashMap<>();
varsMap.put("multiplier", 1);
Map<String, Object> params = new HashMap<>();
params.put("_agg", new ArrayList<>());
params.put("vars", varsMap);
Script initScript = new Script("vars.multiplier = 3", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script mapScript = new Script("_agg.add(vars.multiplier)", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script combineScript = new Script("sum agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
Script reduceScript = new Script("sum aggs of agg values as a new aggregation", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse searchResponse = client().prepareSearch("empty_bucket_idx")
.setQuery(matchAllQuery())
.addAggregation(histogram("histo").field("value").interval(1L).minDocCount(0)
.subAggregation(
scriptedMetric("scripted")
.params(params)
.initScript(new Script("vars.multiplier = 3"))
.mapScript(new Script("_agg.add(vars.multiplier)"))
.combineScript(
new Script(
"newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation"))
.reduceScript(
new Script(
"newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum); return newaggregation"))))
.execute().actionGet();
scriptedMetric("scripted")
.params(params)
.initScript(initScript)
.mapScript(mapScript)
.combineScript(combineScript)
.reduceScript(reduceScript)))
.get();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(2L));
Histogram histo = searchResponse.getAggregations().get("histo");

View File

@ -101,7 +101,7 @@ public class TopHitsIT extends ESIntegTestCase {
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
return Collections.emptyMap();
return Collections.singletonMap("5", script -> "5");
}
}

View File

@ -17,28 +17,30 @@
* under the License.
*/
package org.elasticsearch.messy.tests;
package org.elasticsearch.search.fields;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.Priority;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.support.XContentMapValues;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.index.mapper.internal.TimestampFieldMapper;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.rest.RestStatus;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.lookup.FieldLookup;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.ESIntegTestCase;
import org.joda.time.DateTime;
@ -49,11 +51,13 @@ import java.util.Arrays;
import java.util.Base64;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.function.Function;
import static java.util.Collections.singleton;
import static org.elasticsearch.action.support.WriteRequest.RefreshPolicy.IMMEDIATE;
@ -72,13 +76,82 @@ import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
/**
*
*/
public class SearchFieldsTests extends ESIntegTestCase {
public class SearchFieldsIT extends ESIntegTestCase {
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class);
return pluginList(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
@SuppressWarnings("unchecked")
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("doc['num1'].value", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Doubles num1 = (ScriptDocValues.Doubles) doc.get("num1");
return num1.getValue();
});
scripts.put("doc['num1'].value * factor", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Doubles num1 = (ScriptDocValues.Doubles) doc.get("num1");
Double factor = (Double) vars.get("factor");
return num1.getValue() * factor;
});
scripts.put("doc['date'].date.millis", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Longs date = (ScriptDocValues.Longs) doc.get("date");
return date.getDate().getMillis();
});
scripts.put("_fields['num1'].value", vars -> fieldsScript(vars, "num1"));
scripts.put("_fields._uid.value", vars -> fieldsScript(vars, "_uid"));
scripts.put("_fields._id.value", vars -> fieldsScript(vars, "_id"));
scripts.put("_fields._type.value", vars -> fieldsScript(vars, "_type"));
scripts.put("_source.obj1", vars -> sourceScript(vars, "obj1"));
scripts.put("_source.obj1.test", vars -> sourceScript(vars, "obj1.test"));
scripts.put("_source.obj1.test", vars -> sourceScript(vars, "obj1.test"));
scripts.put("_source.obj2", vars -> sourceScript(vars, "obj2"));
scripts.put("_source.obj2.arr2", vars -> sourceScript(vars, "obj2.arr2"));
scripts.put("_source.arr3", vars -> sourceScript(vars, "arr3"));
scripts.put("return null", vars -> null);
scripts.put("doc['l'].values", vars -> docScript(vars, "l"));
scripts.put("doc['ml'].values", vars -> docScript(vars, "ml"));
scripts.put("doc['d'].values", vars -> docScript(vars, "d"));
scripts.put("doc['md'].values", vars -> docScript(vars, "md"));
scripts.put("doc['s'].values", vars -> docScript(vars, "s"));
scripts.put("doc['ms'].values", vars -> docScript(vars, "ms"));
return scripts;
}
@SuppressWarnings("unchecked")
static Object fieldsScript(Map<String, Object> vars, String fieldName) {
Map<?, ?> fields = (Map) vars.get("_fields");
FieldLookup fieldLookup = (FieldLookup) fields.get(fieldName);
return fieldLookup.getValue();
}
@SuppressWarnings("unchecked")
static Object sourceScript(Map<String, Object> vars, String path) {
Map<String, Object> source = (Map) vars.get("_source");
return XContentMapValues.extractValue(path, source);
}
@SuppressWarnings("unchecked")
static Object docScript(Map<String, Object> vars, String fieldName) {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues<?> values = (ScriptDocValues<?>) doc.get(fieldName);
return values.getValues();
}
}
public void testStoredFields() throws Exception {
@ -127,7 +200,12 @@ public class SearchFieldsTests extends ESIntegTestCase {
assertThat(searchResponse.getHits().getAt(0).fields().get("field3").value().toString(), equalTo("value3"));
searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("*3").addStoredField("field1").addStoredField("field2").execute().actionGet();
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addStoredField("*3")
.addStoredField("field1")
.addStoredField("field2")
.get();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
assertThat(searchResponse.getHits().hits().length, equalTo(1));
assertThat(searchResponse.getHits().getAt(0).fields().size(), equalTo(2));
@ -156,7 +234,11 @@ public class SearchFieldsTests extends ESIntegTestCase {
assertThat(searchResponse.getHits().getAt(0).fields().get("field1").value().toString(), equalTo("value1"));
assertThat(searchResponse.getHits().getAt(0).fields().get("field3").value().toString(), equalTo("value3"));
searchResponse = client().prepareSearch().setQuery(matchAllQuery()).addStoredField("*").addStoredField("_source").execute().actionGet();
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addStoredField("*")
.addStoredField("_source")
.get();
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
assertThat(searchResponse.getHits().hits().length, equalTo(1));
assertThat(searchResponse.getHits().getAt(0).source(), notNullValue());
@ -175,25 +257,37 @@ public class SearchFieldsTests extends ESIntegTestCase {
client().admin().indices().preparePutMapping().setType("type1").setSource(mapping).execute().actionGet();
client().prepareIndex("test", "type1", "1")
.setSource(jsonBuilder().startObject().field("test", "value beck").field("num1", 1.0f).field("date", "1970-01-01T00:00:00").endObject())
.setSource(jsonBuilder().startObject()
.field("test", "value beck")
.field("num1", 1.0f)
.field("date", "1970-01-01T00:00:00")
.endObject())
.execute().actionGet();
client().admin().indices().prepareFlush().execute().actionGet();
client().prepareIndex("test", "type1", "2")
.setSource(jsonBuilder().startObject().field("test", "value beck").field("num1", 2.0f).field("date", "1970-01-01T00:00:25").endObject())
.execute().actionGet();
.setSource(jsonBuilder().startObject()
.field("test", "value beck")
.field("num1", 2.0f)
.field("date", "1970-01-01T00:00:25")
.endObject())
.get();
client().admin().indices().prepareFlush().execute().actionGet();
client().prepareIndex("test", "type1", "3")
.setSource(jsonBuilder().startObject().field("test", "value beck").field("num1", 3.0f).field("date", "1970-01-01T00:02:00").endObject())
.execute().actionGet();
.setSource(jsonBuilder().startObject()
.field("test", "value beck")
.field("num1", 3.0f)
.field("date", "1970-01-01T00:02:00")
.endObject())
.get();
client().admin().indices().refresh(refreshRequest()).actionGet();
logger.info("running doc['num1'].value");
SearchResponse response = client().prepareSearch()
.setQuery(matchAllQuery())
.addSort("num1", SortOrder.ASC)
.addScriptField("sNum1", new Script("doc['num1'].value"))
.addScriptField("sNum1_field", new Script("_fields['num1'].value"))
.addScriptField("date1", new Script("doc['date'].date.millis"))
.addScriptField("sNum1", new Script("doc['num1'].value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addScriptField("sNum1_field", new Script("_fields['num1'].value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addScriptField("date1", new Script("doc['date'].date.millis", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.execute().actionGet();
assertNoFailures(response);
@ -204,48 +298,48 @@ public class SearchFieldsTests extends ESIntegTestCase {
Set<String> fields = new HashSet<>(response.getHits().getAt(0).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(newHashSet("sNum1", "sNum1_field", "date1")));
assertThat((Double) response.getHits().getAt(0).fields().get("sNum1").values().get(0), equalTo(1.0));
assertThat((Double) response.getHits().getAt(0).fields().get("sNum1_field").values().get(0), equalTo(1.0));
assertThat((Long) response.getHits().getAt(0).fields().get("date1").values().get(0), equalTo(0L));
assertThat(response.getHits().getAt(0).fields().get("sNum1").values().get(0), equalTo(1.0));
assertThat(response.getHits().getAt(0).fields().get("sNum1_field").values().get(0), equalTo(1.0));
assertThat(response.getHits().getAt(0).fields().get("date1").values().get(0), equalTo(0L));
assertThat(response.getHits().getAt(1).id(), equalTo("2"));
fields = new HashSet<>(response.getHits().getAt(0).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(newHashSet("sNum1", "sNum1_field", "date1")));
assertThat((Double) response.getHits().getAt(1).fields().get("sNum1").values().get(0), equalTo(2.0));
assertThat((Double) response.getHits().getAt(1).fields().get("sNum1_field").values().get(0), equalTo(2.0));
assertThat((Long) response.getHits().getAt(1).fields().get("date1").values().get(0), equalTo(25000L));
assertThat(response.getHits().getAt(1).fields().get("sNum1").values().get(0), equalTo(2.0));
assertThat(response.getHits().getAt(1).fields().get("sNum1_field").values().get(0), equalTo(2.0));
assertThat(response.getHits().getAt(1).fields().get("date1").values().get(0), equalTo(25000L));
assertThat(response.getHits().getAt(2).id(), equalTo("3"));
fields = new HashSet<>(response.getHits().getAt(0).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(newHashSet("sNum1", "sNum1_field", "date1")));
assertThat((Double) response.getHits().getAt(2).fields().get("sNum1").values().get(0), equalTo(3.0));
assertThat((Double) response.getHits().getAt(2).fields().get("sNum1_field").values().get(0), equalTo(3.0));
assertThat((Long) response.getHits().getAt(2).fields().get("date1").values().get(0), equalTo(120000L));
assertThat(response.getHits().getAt(2).fields().get("sNum1").values().get(0), equalTo(3.0));
assertThat(response.getHits().getAt(2).fields().get("sNum1_field").values().get(0), equalTo(3.0));
assertThat(response.getHits().getAt(2).fields().get("date1").values().get(0), equalTo(120000L));
logger.info("running doc['num1'].value * factor");
Map<String, Object> params = MapBuilder.<String, Object>newMapBuilder().put("factor", 2.0).map();
response = client().prepareSearch()
.setQuery(matchAllQuery())
.addSort("num1", SortOrder.ASC)
.addScriptField("sNum1", new Script("doc['num1'].value * factor", ScriptType.INLINE, null, params))
.execute().actionGet();
.addScriptField("sNum1", new Script("doc['num1'].value * factor", ScriptType.INLINE, CustomScriptPlugin.NAME, params))
.get();
assertThat(response.getHits().totalHits(), equalTo(3L));
assertThat(response.getHits().getAt(0).id(), equalTo("1"));
fields = new HashSet<>(response.getHits().getAt(0).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(singleton("sNum1")));
assertThat((Double) response.getHits().getAt(0).fields().get("sNum1").values().get(0), equalTo(2.0));
assertThat(response.getHits().getAt(0).fields().get("sNum1").values().get(0), equalTo(2.0));
assertThat(response.getHits().getAt(1).id(), equalTo("2"));
fields = new HashSet<>(response.getHits().getAt(0).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(singleton("sNum1")));
assertThat((Double) response.getHits().getAt(1).fields().get("sNum1").values().get(0), equalTo(4.0));
assertThat(response.getHits().getAt(1).fields().get("sNum1").values().get(0), equalTo(4.0));
assertThat(response.getHits().getAt(2).id(), equalTo("3"));
fields = new HashSet<>(response.getHits().getAt(0).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(singleton("sNum1")));
assertThat((Double) response.getHits().getAt(2).fields().get("sNum1").values().get(0), equalTo(6.0));
assertThat(response.getHits().getAt(2).fields().get("sNum1").values().get(0), equalTo(6.0));
}
public void testUidBasedScriptFields() throws Exception {
@ -260,8 +354,11 @@ public class SearchFieldsTests extends ESIntegTestCase {
indexRandom(true, indexRequestBuilders);
SearchResponse response = client().prepareSearch()
.setQuery(matchAllQuery()).addSort("num1", SortOrder.ASC).setSize(numDocs)
.addScriptField("uid", new Script("_fields._uid.value")).get();
.setQuery(matchAllQuery())
.addSort("num1", SortOrder.ASC)
.setSize(numDocs)
.addScriptField("uid", new Script("_fields._uid.value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
assertNoFailures(response);
@ -271,12 +368,15 @@ public class SearchFieldsTests extends ESIntegTestCase {
Set<String> fields = new HashSet<>(response.getHits().getAt(i).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(singleton("uid")));
assertThat((String)response.getHits().getAt(i).fields().get("uid").value(), equalTo("type1#" + Integer.toString(i)));
assertThat(response.getHits().getAt(i).fields().get("uid").value(), equalTo("type1#" + Integer.toString(i)));
}
response = client().prepareSearch()
.setQuery(matchAllQuery()).addSort("num1", SortOrder.ASC).setSize(numDocs)
.addScriptField("id", new Script("_fields._id.value")).get();
.setQuery(matchAllQuery())
.addSort("num1", SortOrder.ASC)
.setSize(numDocs)
.addScriptField("id", new Script("_fields._id.value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
assertNoFailures(response);
@ -286,12 +386,15 @@ public class SearchFieldsTests extends ESIntegTestCase {
Set<String> fields = new HashSet<>(response.getHits().getAt(i).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(singleton("id")));
assertThat((String)response.getHits().getAt(i).fields().get("id").value(), equalTo(Integer.toString(i)));
assertThat(response.getHits().getAt(i).fields().get("id").value(), equalTo(Integer.toString(i)));
}
response = client().prepareSearch()
.setQuery(matchAllQuery()).addSort("num1", SortOrder.ASC).setSize(numDocs)
.addScriptField("type", new Script("_fields._type.value")).get();
.setQuery(matchAllQuery())
.addSort("num1", SortOrder.ASC)
.setSize(numDocs)
.addScriptField("type", new Script("_fields._type.value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
assertNoFailures(response);
@ -301,13 +404,17 @@ public class SearchFieldsTests extends ESIntegTestCase {
Set<String> fields = new HashSet<>(response.getHits().getAt(i).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(singleton("type")));
assertThat((String)response.getHits().getAt(i).fields().get("type").value(), equalTo("type1"));
assertThat(response.getHits().getAt(i).fields().get("type").value(), equalTo("type1"));
}
response = client().prepareSearch()
.setQuery(matchAllQuery()).addSort("num1", SortOrder.ASC).setSize(numDocs)
.addScriptField("id", new Script("_fields._id.value")).addScriptField("uid", new Script("_fields._uid.value"))
.addScriptField("type", new Script("_fields._type.value")).get();
.setQuery(matchAllQuery())
.addSort("num1", SortOrder.ASC)
.setSize(numDocs)
.addScriptField("id", new Script("_fields._id.value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addScriptField("uid", new Script("_fields._uid.value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addScriptField("type", new Script("_fields._type.value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
assertNoFailures(response);
@ -317,9 +424,9 @@ public class SearchFieldsTests extends ESIntegTestCase {
Set<String> fields = new HashSet<>(response.getHits().getAt(i).fields().keySet());
fields.remove(TimestampFieldMapper.NAME); // randomly enabled via templates
assertThat(fields, equalTo(newHashSet("uid", "type", "id")));
assertThat((String)response.getHits().getAt(i).fields().get("uid").value(), equalTo("type1#" + Integer.toString(i)));
assertThat((String)response.getHits().getAt(i).fields().get("type").value(), equalTo("type1"));
assertThat((String)response.getHits().getAt(i).fields().get("id").value(), equalTo(Integer.toString(i)));
assertThat(response.getHits().getAt(i).fields().get("uid").value(), equalTo("type1#" + Integer.toString(i)));
assertThat(response.getHits().getAt(i).fields().get("type").value(), equalTo("type1"));
assertThat(response.getHits().getAt(i).fields().get("id").value(), equalTo(Integer.toString(i)));
}
}
@ -335,10 +442,14 @@ public class SearchFieldsTests extends ESIntegTestCase {
.execute().actionGet();
client().admin().indices().refresh(refreshRequest()).actionGet();
SearchResponse response = client().prepareSearch().setQuery(matchAllQuery()).addScriptField("s_obj1", new Script("_source.obj1"))
.addScriptField("s_obj1_test", new Script("_source.obj1.test")).addScriptField("s_obj2", new Script("_source.obj2"))
.addScriptField("s_obj2_arr2", new Script("_source.obj2.arr2")).addScriptField("s_arr3", new Script("_source.arr3"))
.execute().actionGet();
SearchResponse response = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("s_obj1", new Script("_source.obj1", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addScriptField("s_obj1_test", new Script("_source.obj1.test", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addScriptField("s_obj2", new Script("_source.obj2", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addScriptField("s_obj2_arr2", new Script("_source.obj2.arr2", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addScriptField("s_arr3", new Script("_source.arr3", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
assertThat("Failures " + Arrays.toString(response.getShardFailures()), response.getShardFailures().length, equalTo(0));
@ -365,12 +476,13 @@ public class SearchFieldsTests extends ESIntegTestCase {
public void testScriptFieldsForNullReturn() throws Exception {
client().prepareIndex("test", "type1", "1")
.setSource("foo", "bar")
.setRefreshPolicy("true").get();
.setSource("foo", "bar")
.setRefreshPolicy("true").get();
SearchResponse response = client().prepareSearch().setQuery(matchAllQuery())
.addScriptField("test_script_1", new Script("return null"))
.get();
SearchResponse response = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("test_script_1", new Script("return null", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
assertNoFailures(response);
@ -401,17 +513,53 @@ public class SearchFieldsTests extends ESIntegTestCase {
public void testStoredFieldsWithoutSource() throws Exception {
createIndex("test");
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("_source").field("enabled", false).endObject().startObject("properties")
.startObject("byte_field").field("type", "byte").field("store", true).endObject()
.startObject("short_field").field("type", "short").field("store", true).endObject()
.startObject("integer_field").field("type", "integer").field("store", true).endObject()
.startObject("long_field").field("type", "long").field("store", true).endObject()
.startObject("float_field").field("type", "float").field("store", true).endObject()
.startObject("double_field").field("type", "double").field("store", true).endObject()
.startObject("date_field").field("type", "date").field("store", true).endObject()
.startObject("boolean_field").field("type", "boolean").field("store", true).endObject()
.startObject("binary_field").field("type", "binary").field("store", true).endObject()
.endObject().endObject().endObject().string();
String mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("type1")
.startObject("_source")
.field("enabled", false)
.endObject()
.startObject("properties")
.startObject("byte_field")
.field("type", "byte")
.field("store", true)
.endObject()
.startObject("short_field")
.field("type", "short")
.field("store", true)
.endObject()
.startObject("integer_field")
.field("type", "integer")
.field("store", true)
.endObject()
.startObject("long_field")
.field("type", "long")
.field("store", true)
.endObject()
.startObject("float_field")
.field("type", "float")
.field("store", true)
.endObject()
.startObject("double_field")
.field("type", "double")
.field("store", true)
.endObject()
.startObject("date_field")
.field("type", "date")
.field("store", true)
.endObject()
.startObject("boolean_field")
.field("type", "boolean")
.field("store", true)
.endObject()
.startObject("binary_field")
.field("type", "binary")
.field("store", true)
.endObject()
.endObject()
.endObject()
.endObject()
.string();
client().admin().indices().preparePutMapping().setType("type1").setSource(mapping).execute().actionGet();
@ -449,17 +597,17 @@ public class SearchFieldsTests extends ESIntegTestCase {
"float_field", "double_field", "date_field", "boolean_field", "binary_field")));
assertThat(searchResponse.getHits().getAt(0).fields().get("byte_field").value().toString(), equalTo("1"));
assertThat(searchResponse.getHits().getAt(0).fields().get("short_field").value().toString(), equalTo("2"));
assertThat(searchResponse.getHits().getAt(0).fields().get("integer_field").value(), equalTo((Object) 3));
assertThat(searchResponse.getHits().getAt(0).fields().get("long_field").value(), equalTo((Object) 4L));
assertThat(searchResponse.getHits().getAt(0).fields().get("float_field").value(), equalTo((Object) 5.0f));
assertThat(searchResponse.getHits().getAt(0).fields().get("double_field").value(), equalTo((Object) 6.0d));
SearchHit searchHit = searchResponse.getHits().getAt(0);
assertThat(searchHit.fields().get("byte_field").value().toString(), equalTo("1"));
assertThat(searchHit.fields().get("short_field").value().toString(), equalTo("2"));
assertThat(searchHit.fields().get("integer_field").value(), equalTo((Object) 3));
assertThat(searchHit.fields().get("long_field").value(), equalTo((Object) 4L));
assertThat(searchHit.fields().get("float_field").value(), equalTo((Object) 5.0f));
assertThat(searchHit.fields().get("double_field").value(), equalTo((Object) 6.0d));
String dateTime = Joda.forPattern("dateOptionalTime").printer().print(new DateTime(2012, 3, 22, 0, 0, DateTimeZone.UTC));
assertThat(searchResponse.getHits().getAt(0).fields().get("date_field").value(), equalTo((Object) dateTime));
assertThat(searchResponse.getHits().getAt(0).fields().get("boolean_field").value(), equalTo((Object) Boolean.TRUE));
assertThat(((BytesReference) searchResponse.getHits().getAt(0).fields().get("binary_field").value()), equalTo((BytesReference) new BytesArray("testing text".getBytes("UTF8"))));
assertThat(searchHit.fields().get("date_field").value(), equalTo((Object) dateTime));
assertThat(searchHit.fields().get("boolean_field").value(), equalTo((Object) Boolean.TRUE));
assertThat(searchHit.fields().get("binary_field").value(), equalTo(new BytesArray("testing text" .getBytes("UTF8"))));
}
public void testSearchFieldsMetaData() throws Exception {
@ -575,25 +723,57 @@ public class SearchFieldsTests extends ESIntegTestCase {
new SearchSourceBuilder().query(QueryBuilders.matchAllQuery()).fieldDataField("test_field")).get();
assertHitCount(searchResponse, 1);
Map<String,SearchHitField> fields = searchResponse.getHits().getHits()[0].getFields();
assertThat((String)fields.get("test_field").value(), equalTo("foobar"));
assertThat(fields.get("test_field").value(), equalTo("foobar"));
}
public void testFieldsPulledFromFieldData() throws Exception {
createIndex("test");
String mapping = XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("_source").field("enabled", false).endObject().startObject("properties")
.startObject("text_field").field("type", "text").field("fielddata", true).endObject()
.startObject("keyword_field").field("type", "keyword").endObject()
.startObject("byte_field").field("type", "byte").endObject()
.startObject("short_field").field("type", "short").endObject()
.startObject("integer_field").field("type", "integer").endObject()
.startObject("long_field").field("type", "long").endObject()
.startObject("float_field").field("type", "float").endObject()
.startObject("double_field").field("type", "double").endObject()
.startObject("date_field").field("type", "date").endObject()
.startObject("boolean_field").field("type", "boolean").endObject()
.startObject("binary_field").field("type", "binary").endObject()
.endObject().endObject().endObject().string();
String mapping = XContentFactory.jsonBuilder()
.startObject()
.startObject("type1")
.startObject("_source")
.field("enabled", false)
.endObject()
.startObject("properties")
.startObject("text_field")
.field("type", "text")
.field("fielddata", true)
.endObject()
.startObject("keyword_field")
.field("type", "keyword")
.endObject()
.startObject("byte_field")
.field("type", "byte")
.endObject()
.startObject("short_field")
.field("type", "short")
.endObject()
.startObject("integer_field")
.field("type", "integer")
.endObject()
.startObject("long_field")
.field("type", "long")
.endObject()
.startObject("float_field")
.field("type", "float")
.endObject()
.startObject("double_field")
.field("type", "double")
.endObject()
.startObject("date_field")
.field("type", "date")
.endObject()
.startObject("boolean_field")
.field("type", "boolean")
.endObject()
.startObject("binary_field")
.field("type", "binary")
.endObject()
.endObject()
.endObject()
.endObject()
.string();
client().admin().indices().preparePutMapping().setType("type1").setSource(mapping).execute().actionGet();
@ -667,7 +847,7 @@ public class SearchFieldsTests extends ESIntegTestCase {
ensureSearchable();
SearchRequestBuilder req = client().prepareSearch("index");
for (String field : Arrays.asList("s", "ms", "l", "ml", "d", "md")) {
req.addScriptField(field, new Script("doc['" + field + "'].values"));
req.addScriptField(field, new Script("doc['" + field + "'].values", ScriptType.INLINE, CustomScriptPlugin.NAME, null));
}
SearchResponse resp = req.get();
assertSearchResponse(resp);
@ -690,11 +870,11 @@ public class SearchFieldsTests extends ESIntegTestCase {
indexRandom(true,
client().prepareIndex("test", "my-type1", "1")
.setRouting("1")
.setTimestamp("205097")
.setTTL(10000000000000L)
.setParent("parent_1")
.setSource(jsonBuilder().startObject().field("field1", "value").endObject()));
.setRouting("1")
.setTimestamp("205097")
.setTTL(10000000000000L)
.setParent("parent_1")
.setSource(jsonBuilder().startObject().field("field1", "value").endObject()));
SearchResponse response = client().prepareSearch("test").addStoredField("field1").get();
assertSearchResponse(response);

View File

@ -16,26 +16,27 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.messy.tests;
package org.elasticsearch.search.functionscore;
import org.apache.lucene.util.ArrayUtil;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.index.query.functionscore.FunctionScoreQueryBuilder;
import org.elasticsearch.index.query.functionscore.RandomScoreFunctionBuilder;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.ScoreAccessor;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.test.ESIntegTestCase;
import org.hamcrest.CoreMatchers;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.functionScoreQuery;
@ -44,6 +45,7 @@ import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.fieldValueFactorFunction;
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.randomFunction;
import static org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders.scriptFunction;
import static org.elasticsearch.script.MockScriptPlugin.NAME;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.allOf;
@ -54,11 +56,41 @@ import static org.hamcrest.Matchers.greaterThanOrEqualTo;
import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.nullValue;
public class RandomScoreFunctionTests extends ESIntegTestCase {
public class RandomScoreFunctionIT extends ESIntegTestCase {
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class);
return pluginList(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
@SuppressWarnings("unchecked")
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("log(doc['index'].value + (factor * _score))",
vars -> scoringScript(vars, ScoreAccessor::doubleValue));
scripts.put("log(doc['index'].value + (factor * _score.intValue()))",
vars -> scoringScript(vars, ScoreAccessor::intValue));
scripts.put("log(doc['index'].value + (factor * _score.longValue()))",
vars -> scoringScript(vars, ScoreAccessor::longValue));
scripts.put("log(doc['index'].value + (factor * _score.floatValue()))",
vars -> scoringScript(vars, ScoreAccessor::floatValue));
scripts.put("log(doc['index'].value + (factor * _score.doubleValue()))",
vars -> scoringScript(vars, ScoreAccessor::doubleValue));
return scripts;
}
@SuppressWarnings("unchecked")
static Double scoringScript(Map<String, Object> vars, Function<ScoreAccessor, Number> scoring) {
Map<?, ?> doc = (Map) vars.get("doc");
Double index = ((Number) ((ScriptDocValues<?>) doc.get("index")).getValues().get(0)).doubleValue();
Double score = scoring.apply((ScoreAccessor) vars.get("_score")).doubleValue();
Integer factor = (Integer) vars.get("factor");
return Math.log(index + (factor * score));
}
}
public void testConsistentHitsWithSameSeed() throws Exception {
@ -86,17 +118,15 @@ public class RandomScoreFunctionTests extends ESIntegTestCase {
.setPreference(preference)
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(seed)))
.execute().actionGet();
assertThat("Failures " + Arrays.toString(searchResponse.getShardFailures()), searchResponse.getShardFailures().length, CoreMatchers.equalTo(0));
assertThat("Failures " + Arrays.toString(searchResponse.getShardFailures()),
searchResponse.getShardFailures().length, CoreMatchers.equalTo(0));
final int hitCount = searchResponse.getHits().getHits().length;
final SearchHit[] currentHits = searchResponse.getHits().getHits();
ArrayUtil.timSort(currentHits, new Comparator<SearchHit>() {
@Override
public int compare(SearchHit o1, SearchHit o2) {
// for tie-breaking we have to resort here since if the score is
// identical we rely on collection order which might change.
int cmp = Float.compare(o1.getScore(), o2.getScore());
return cmp == 0 ? o1.getId().compareTo(o2.getId()) : cmp;
}
ArrayUtil.timSort(currentHits, (o1, o2) -> {
// for tie-breaking we have to resort here since if the score is
// identical we rely on collection order which might change.
int cmp = Float.compare(o1.getScore(), o2.getScore());
return cmp == 0 ? o1.getId().compareTo(o2.getId()) : cmp;
});
if (i == 0) {
assertThat(hits, nullValue());
@ -128,71 +158,92 @@ public class RandomScoreFunctionTests extends ESIntegTestCase {
int docCount = randomIntBetween(100, 200);
for (int i = 0; i < docCount; i++) {
client().prepareIndex("test", "type", "" + i).setSource("body", randomFrom(Arrays.asList("foo", "bar", "baz")), "index", i + 1) // we add 1 to the index field to make sure that the scripts below never compute log(0)
client().prepareIndex("test", "type", "" + i)
// we add 1 to the index field to make sure that the scripts below never compute log(0)
.setSource("body", randomFrom(Arrays.asList("foo", "bar", "baz")), "index", i + 1)
.get();
}
refresh();
Map<String, Object> params = new HashMap<>();
params.put("factor", randomIntBetween(2, 4));
// Test for accessing _score
Script script = new Script("log(doc['index'].value + (factor * _score))", ScriptType.INLINE, NAME, params);
SearchResponse resp = client()
.prepareSearch("test")
.setQuery(
functionScoreQuery(matchQuery("body", "foo"), new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(fieldValueFactorFunction("index").factor(2)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(new Script("log(doc['index'].value + (factor * _score))", ScriptType.INLINE, null, params)))
})).get();
functionScoreQuery(matchQuery("body", "foo"),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
new FunctionScoreQueryBuilder.FilterFunctionBuilder(fieldValueFactorFunction("index").factor(2)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(script))
}
))
.get();
assertNoFailures(resp);
SearchHit firstHit = resp.getHits().getAt(0);
assertThat(firstHit.getScore(), greaterThan(1f));
// Test for accessing _score.intValue()
script = new Script("log(doc['index'].value + (factor * _score.intValue()))", ScriptType.INLINE, NAME, params);
resp = client()
.prepareSearch("test")
.setQuery(
functionScoreQuery(matchQuery("body", "foo"), new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(fieldValueFactorFunction("index").factor(2)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(new Script("log(doc['index'].value + (factor * _score.intValue()))", ScriptType.INLINE, null, params)))
})).get();
functionScoreQuery(matchQuery("body", "foo"),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
new FunctionScoreQueryBuilder.FilterFunctionBuilder(fieldValueFactorFunction("index").factor(2)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(script))
}
))
.get();
assertNoFailures(resp);
firstHit = resp.getHits().getAt(0);
assertThat(firstHit.getScore(), greaterThan(1f));
// Test for accessing _score.longValue()
script = new Script("log(doc['index'].value + (factor * _score.longValue()))", ScriptType.INLINE, NAME, params);
resp = client()
.prepareSearch("test")
.setQuery(
functionScoreQuery(matchQuery("body", "foo"), new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(fieldValueFactorFunction("index").factor(2)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(new Script("log(doc['index'].value + (factor * _score.longValue()))", ScriptType.INLINE, null, params)))
})).get();
functionScoreQuery(matchQuery("body", "foo"),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
new FunctionScoreQueryBuilder.FilterFunctionBuilder(fieldValueFactorFunction("index").factor(2)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(script))
}
))
.get();
assertNoFailures(resp);
firstHit = resp.getHits().getAt(0);
assertThat(firstHit.getScore(), greaterThan(1f));
// Test for accessing _score.floatValue()
script = new Script("log(doc['index'].value + (factor * _score.floatValue()))", ScriptType.INLINE, NAME, params);
resp = client()
.prepareSearch("test")
.setQuery(
functionScoreQuery(matchQuery("body", "foo"), new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
new FunctionScoreQueryBuilder.FilterFunctionBuilder(fieldValueFactorFunction("index").factor(2)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(new Script("log(doc['index'].value + (factor * _score.floatValue()))",
ScriptType.INLINE, null, params)))
})).get();
functionScoreQuery(matchQuery("body", "foo"),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
new FunctionScoreQueryBuilder.FilterFunctionBuilder(fieldValueFactorFunction("index").factor(2)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(script))
}
))
.get();
assertNoFailures(resp);
firstHit = resp.getHits().getAt(0);
assertThat(firstHit.getScore(), greaterThan(1f));
// Test for accessing _score.doubleValue()
script = new Script("log(doc['index'].value + (factor * _score.doubleValue()))", ScriptType.INLINE, NAME, params);
resp = client()
.prepareSearch("test")
.setQuery(
functionScoreQuery(matchQuery("body", "foo"), new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
functionScoreQuery(matchQuery("body", "foo"),
new FunctionScoreQueryBuilder.FilterFunctionBuilder[] {
new FunctionScoreQueryBuilder.FilterFunctionBuilder(fieldValueFactorFunction("index").factor(2)),
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(new Script("log(doc['index'].value + (factor * _score.doubleValue()))",
ScriptType.INLINE, null, params)))
})).get();
new FunctionScoreQueryBuilder.FilterFunctionBuilder(scriptFunction(script))
}
))
.get();
assertNoFailures(resp);
firstHit = resp.getHits().getAt(0);
assertThat(firstHit.getScore(), greaterThan(1f));
@ -208,9 +259,9 @@ public class RandomScoreFunctionTests extends ESIntegTestCase {
int seed = 12345678;
SearchResponse resp = client().prepareSearch("test")
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(seed)))
.setExplain(true)
.get();
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(seed)))
.setExplain(true)
.get();
assertNoFailures(resp);
assertEquals(1, resp.getHits().totalHits());
SearchHit firstHit = resp.getHits().getAt(0);
@ -222,8 +273,8 @@ public class RandomScoreFunctionTests extends ESIntegTestCase {
ensureGreen();
SearchResponse resp = client().prepareSearch("test")
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(1234)))
.get();
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(1234)))
.get();
assertNoFailures(resp);
assertEquals(0, resp.getHits().totalHits());
}
@ -243,9 +294,9 @@ public class RandomScoreFunctionTests extends ESIntegTestCase {
for (int i = 0; i < iters; ++i) {
int seed = randomInt();
SearchResponse searchResponse = client().prepareSearch()
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(seed)))
.setSize(docCount)
.execute().actionGet();
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(seed)))
.setSize(docCount)
.execute().actionGet();
assertNoFailures(searchResponse);
for (SearchHit hit : searchResponse.getHits().getHits()) {
@ -264,19 +315,19 @@ public class RandomScoreFunctionTests extends ESIntegTestCase {
flushAndRefresh();
assertNoFailures(client().prepareSearch()
.setSize(docCount) // get all docs otherwise we are prone to tie-breaking
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(randomInt())))
.execute().actionGet());
.setSize(docCount) // get all docs otherwise we are prone to tie-breaking
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(randomInt())))
.execute().actionGet());
assertNoFailures(client().prepareSearch()
.setSize(docCount) // get all docs otherwise we are prone to tie-breaking
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(randomLong())))
.execute().actionGet());
.setSize(docCount) // get all docs otherwise we are prone to tie-breaking
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(randomLong())))
.execute().actionGet());
assertNoFailures(client().prepareSearch()
.setSize(docCount) // get all docs otherwise we are prone to tie-breaking
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(randomRealisticUnicodeOfLengthBetween(10, 20))))
.execute().actionGet());
.setSize(docCount) // get all docs otherwise we are prone to tie-breaking
.setQuery(functionScoreQuery(matchAllQuery(), randomFunction(randomRealisticUnicodeOfLengthBetween(10, 20))))
.execute().actionGet());
}
public void checkDistribution() throws Exception {
@ -344,5 +395,4 @@ public class RandomScoreFunctionTests extends ESIntegTestCase {
logger.info("mean: {}", sum / (double) count);
}
}

View File

@ -17,7 +17,7 @@
* under the License.
*/
package org.elasticsearch.messy.tests;
package org.elasticsearch.search.geo;
import org.elasticsearch.Version;
import org.elasticsearch.action.search.SearchResponse;
@ -27,32 +27,71 @@ import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.unit.DistanceUnit;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.InternalSettingsPlugin;
import org.elasticsearch.test.VersionUtils;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.script.ScriptService.ScriptType;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.closeTo;
/**
*/
public class GeoDistanceTests extends ESIntegTestCase {
public class GeoDistanceIT extends ESIntegTestCase {
private static final double source_lat = 32.798;
private static final double source_long = -117.151;
private static final double target_lat = 32.81;
private static final double target_long = -117.21;
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return pluginList(GroovyPlugin.class, InternalSettingsPlugin.class);
return pluginList(CustomScriptPlugin.class, InternalSettingsPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
@SuppressWarnings("unchecked")
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("arcDistance", vars -> distanceScript(vars,
location -> location.arcDistance(target_lat, target_long)));
scripts.put("distance", vars -> distanceScript(vars,
location -> location.distance(target_lat, target_long)));
scripts.put("arcDistanceInKm", vars -> distanceScript(vars,
location -> location.arcDistanceInKm(target_lat, target_long)));
scripts.put("distanceInKm", vars -> distanceScript(vars,
location -> location.distanceInKm(target_lat, target_long)));
scripts.put("arcDistanceInKm(lat, lon + 360)", vars -> distanceScript(vars,
location -> location.arcDistanceInKm(target_lat, target_long + 360)));
scripts.put("arcDistanceInKm(lat + 360, lon)", vars -> distanceScript(vars,
location -> location.arcDistanceInKm(target_lat + 360, target_long)));
scripts.put("arcDistanceInMiles", vars -> distanceScript(vars,
location -> location.arcDistanceInMiles(target_lat, target_long)));
scripts.put("distanceInMiles", vars -> distanceScript(vars,
location -> location.distanceInMiles(target_lat, target_long)));
return scripts;
}
@SuppressWarnings("unchecked")
static Double distanceScript(Map<String, Object> vars, Function<ScriptDocValues.GeoPoints, Double> distance) {
Map<?, ?> doc = (Map) vars.get("doc");
return distance.apply((ScriptDocValues.GeoPoints) doc.get("location"));
}
}
public void testDistanceScript() throws Exception {
double source_lat = 32.798;
double source_long = -117.151;
double target_lat = 32.81;
double target_long = -117.21;
Version version = VersionUtils.randomVersionBetween(random(), Version.V_2_0_0, Version.CURRENT);
Settings settings = Settings.builder().put(IndexMetaData.SETTING_VERSION_CREATED, version).build();
@ -65,69 +104,78 @@ public class GeoDistanceTests extends ESIntegTestCase {
assertAcked(prepareCreate("test").setSettings(settings).addMapping("type1", xContentBuilder));
ensureGreen();
client().prepareIndex("test", "type1", "1").setSource(jsonBuilder().startObject()
.field("name", "TestPosition")
.startObject("location").field("lat", source_lat).field("lon", source_long).endObject()
.endObject()).execute().actionGet();
client().prepareIndex("test", "type1", "1")
.setSource(jsonBuilder().startObject()
.field("name", "TestPosition")
.startObject("location")
.field("lat", source_lat)
.field("lon", source_long)
.endObject()
.endObject())
.get();
refresh();
// Test doc['location'].arcDistance(lat, lon)
SearchResponse searchResponse1 = client().prepareSearch().addStoredField("_source")
.addScriptField("distance", new Script("doc['location'].arcDistance(" + target_lat + "," + target_long + ")")).execute()
.actionGet();
.addScriptField("distance", new Script("arcDistance", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
Double resultDistance1 = searchResponse1.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultDistance1,
closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.DEFAULT), 0.01d));
// Test doc['location'].distance(lat, lon)
SearchResponse searchResponse2 = client().prepareSearch().addStoredField("_source")
.addScriptField("distance", new Script("doc['location'].distance(" + target_lat + "," + target_long + ")")).execute()
.actionGet();
.addScriptField("distance", new Script("distance", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
Double resultDistance2 = searchResponse2.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultDistance2,
closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.DEFAULT), 0.01d));
// Test doc['location'].arcDistanceInKm(lat, lon)
SearchResponse searchResponse3 = client().prepareSearch().addStoredField("_source")
.addScriptField("distance", new Script("doc['location'].arcDistanceInKm(" + target_lat + "," + target_long + ")"))
.execute().actionGet();
.addScriptField("distance", new Script("arcDistanceInKm", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
Double resultArcDistance3 = searchResponse3.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultArcDistance3,
closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.KILOMETERS), 0.01d));
// Test doc['location'].distanceInKm(lat, lon)
SearchResponse searchResponse4 = client().prepareSearch().addStoredField("_source")
.addScriptField("distance", new Script("doc['location'].distanceInKm(" + target_lat + "," + target_long + ")")).execute()
.actionGet();
.addScriptField("distance", new Script("distanceInKm", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
Double resultDistance4 = searchResponse4.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultDistance4,
closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.KILOMETERS), 0.01d));
SearchResponse searchResponse5 = client()
.prepareSearch()
.addStoredField("_source")
.addScriptField("distance", new Script("doc['location'].arcDistanceInKm(" + (target_lat) + "," + (target_long + 360) + ")"))
.execute().actionGet();
// Test doc['location'].arcDistanceInKm(lat, lon + 360)
SearchResponse searchResponse5 = client().prepareSearch().addStoredField("_source")
.addScriptField("distance", new Script("arcDistanceInKm(lat, lon + 360)", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
Double resultArcDistance5 = searchResponse5.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultArcDistance5,
closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.KILOMETERS), 0.01d));
SearchResponse searchResponse6 = client()
.prepareSearch()
.addStoredField("_source")
.addScriptField("distance", new Script("doc['location'].arcDistanceInKm(" + (target_lat + 360) + "," + (target_long) + ")"))
.execute().actionGet();
// Test doc['location'].arcDistanceInKm(lat + 360, lon)
SearchResponse searchResponse6 = client().prepareSearch().addStoredField("_source")
.addScriptField("distance", new Script("arcDistanceInKm(lat + 360, lon)", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
Double resultArcDistance6 = searchResponse6.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultArcDistance6,
closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.KILOMETERS), 0.01d));
// Test doc['location'].arcDistanceInMiles(lat, lon)
SearchResponse searchResponse7 = client().prepareSearch().addStoredField("_source")
.addScriptField("distance", new Script("doc['location'].arcDistanceInMiles(" + target_lat + "," + target_long + ")"))
.execute().actionGet();
.addScriptField("distance", new Script("arcDistanceInMiles", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
Double resultDistance7 = searchResponse7.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultDistance7,
closeTo(GeoDistance.ARC.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.01d));
// Test doc['location'].distanceInMiles(lat, lon)
SearchResponse searchResponse8 = client().prepareSearch().addStoredField("_source")
.addScriptField("distance", new Script("doc['location'].distanceInMiles(" + target_lat + "," + target_long + ")"))
.execute().actionGet();
.addScriptField("distance", new Script("distanceInMiles", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
Double resultDistance8 = searchResponse8.getHits().getHits()[0].getFields().get("distance").getValue();
assertThat(resultDistance8,
closeTo(GeoDistance.PLANE.calculate(source_lat, source_long, target_lat, target_long, DistanceUnit.MILES), 0.01d));

View File

@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.messy.tests;
package org.elasticsearch.search.geo;
import org.elasticsearch.cluster.ClusterState;
import org.elasticsearch.cluster.routing.IndexShardRoutingTable;
@ -26,25 +26,13 @@ import org.elasticsearch.index.IndexService;
import org.elasticsearch.index.mapper.MappedFieldType;
import org.elasticsearch.index.mapper.geo.GeoShapeFieldMapper;
import org.elasticsearch.indices.IndicesService;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.test.ESIntegTestCase;
import java.util.Collection;
import java.util.Collections;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
/**
*/
public class GeoShapeIntegrationTests extends ESIntegTestCase {
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class);
}
public class GeoShapeIntegrationIT extends ESIntegTestCase {
/**
* Test that orientation parameter correctly persists across cluster restart

View File

@ -83,7 +83,7 @@ public class InnerHitsIT extends ESIntegTestCase {
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
return Collections.emptyMap();
return Collections.singletonMap("5", script -> "5");
}
}

View File

@ -17,15 +17,16 @@
* under the License.
*/
package org.elasticsearch.messy.tests;
package org.elasticsearch.search.scriptfilter;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.index.IndexModule;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.ESIntegTestCase;
@ -34,19 +35,47 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.scriptQuery;
import static org.hamcrest.Matchers.equalTo;
/**
*
*/
@ESIntegTestCase.ClusterScope(scope= ESIntegTestCase.Scope.SUITE)
public class ScriptQuerySearchTests extends ESIntegTestCase {
public class ScriptQuerySearchIT extends ESIntegTestCase {
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class);
return Collections.singleton(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("doc['num1'].value", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
return doc.get("num1");
});
scripts.put("doc['num1'].value > 1", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Doubles num1 = (ScriptDocValues.Doubles) doc.get("num1");
return num1.getValue() > 1;
});
scripts.put("doc['num1'].value > param1", vars -> {
Integer param1 = (Integer) vars.get("param1");
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues.Doubles num1 = (ScriptDocValues.Doubles) doc.get("num1");
return num1.getValue() > param1;
});
return scripts;
}
}
@Override
@ -62,21 +91,23 @@ public class ScriptQuerySearchTests extends ESIntegTestCase {
createIndex("test");
client().prepareIndex("test", "type1", "1")
.setSource(jsonBuilder().startObject().field("test", "value beck").field("num1", 1.0f).endObject())
.execute().actionGet();
.get();
flush();
client().prepareIndex("test", "type1", "2")
.setSource(jsonBuilder().startObject().field("test", "value beck").field("num1", 2.0f).endObject())
.execute().actionGet();
.get();
flush();
client().prepareIndex("test", "type1", "3")
.setSource(jsonBuilder().startObject().field("test", "value beck").field("num1", 3.0f).endObject())
.execute().actionGet();
.get();
refresh();
logger.info("running doc['num1'].value > 1");
SearchResponse response = client().prepareSearch()
.setQuery(scriptQuery(new Script("doc['num1'].value > 1"))).addSort("num1", SortOrder.ASC)
.addScriptField("sNum1", new Script("doc['num1'].value")).execute().actionGet();
.setQuery(scriptQuery(new Script("doc['num1'].value > 1", ScriptType.INLINE, CustomScriptPlugin.NAME, null)))
.addSort("num1", SortOrder.ASC)
.addScriptField("sNum1", new Script("doc['num1'].value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
assertThat(response.getHits().totalHits(), equalTo(2L));
assertThat(response.getHits().getAt(0).id(), equalTo("2"));
@ -90,8 +121,10 @@ public class ScriptQuerySearchTests extends ESIntegTestCase {
logger.info("running doc['num1'].value > param1");
response = client()
.prepareSearch()
.setQuery(scriptQuery(new Script("doc['num1'].value > param1", ScriptType.INLINE, null, params)))
.addSort("num1", SortOrder.ASC).addScriptField("sNum1", new Script("doc['num1'].value")).execute().actionGet();
.setQuery(scriptQuery(new Script("doc['num1'].value > param1", ScriptType.INLINE, CustomScriptPlugin.NAME, params)))
.addSort("num1", SortOrder.ASC)
.addScriptField("sNum1", new Script("doc['num1'].value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
assertThat(response.getHits().totalHits(), equalTo(1L));
assertThat(response.getHits().getAt(0).id(), equalTo("3"));
@ -102,9 +135,10 @@ public class ScriptQuerySearchTests extends ESIntegTestCase {
logger.info("running doc['num1'].value > param1");
response = client()
.prepareSearch()
.setQuery(
scriptQuery(new Script("doc['num1'].value > param1", ScriptType.INLINE, null, params)))
.addSort("num1", SortOrder.ASC).addScriptField("sNum1", new Script("doc['num1'].value")).execute().actionGet();
.setQuery(scriptQuery(new Script("doc['num1'].value > param1", ScriptType.INLINE, CustomScriptPlugin.NAME, params)))
.addSort("num1", SortOrder.ASC)
.addScriptField("sNum1", new Script("doc['num1'].value", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.get();
assertThat(response.getHits().totalHits(), equalTo(3L));
assertThat(response.getHits().getAt(0).id(), equalTo("1"));

View File

@ -0,0 +1,476 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.search.sort;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.common.geo.GeoPoint;
import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.fielddata.ScriptDocValues;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.ScriptSortBuilder.ScriptSortType;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.InternalSettingsPlugin;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.function.Function;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.script.ScriptService.ScriptType;
import static org.elasticsearch.search.sort.SortBuilders.scriptSort;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
public class SimpleSortIT extends ESIntegTestCase {
private static final String DOUBLE_APOSTROPHE = "\u0027\u0027";
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return pluginList(CustomScriptPlugin.class, InternalSettingsPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("doc['str_value'].value", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
return ((ScriptDocValues.Strings) doc.get("str_value")).getValue();
});
scripts.put("doc['id'].value", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
return ((ScriptDocValues.Strings) doc.get("id")).getValue();
});
scripts.put("doc['id'].values[0]", vars -> {
Map<?, ?> doc = (Map) vars.get("doc");
return ((ScriptDocValues.Strings) doc.get("id")).getValues().get(0);
});
scripts.put("get min long", vars -> getMinValueScript(vars, Long.MAX_VALUE, "lvalue", l -> (Long) l));
scripts.put("get min double", vars -> getMinValueScript(vars, Double.MAX_VALUE, "dvalue", d -> (Double) d));
scripts.put("get min string", vars -> getMinValueScript(vars, Integer.MAX_VALUE, "svalue", s -> Integer.parseInt((String) s)));
scripts.put("get min geopoint lon", vars -> getMinValueScript(vars, Double.MAX_VALUE, "gvalue", g -> ((GeoPoint) g).getLon()));
scripts.put(DOUBLE_APOSTROPHE, vars -> DOUBLE_APOSTROPHE);
return scripts;
}
/**
* Return the minimal value from a set of values.
*/
@SuppressWarnings("unchecked")
static <T extends Comparable<T>> T getMinValueScript(Map<String, Object> vars, T initialValue, String fieldName,
Function<Object, T> converter) {
T retval = initialValue;
Map<?, ?> doc = (Map) vars.get("doc");
ScriptDocValues<?> values = (ScriptDocValues<?>) doc.get(fieldName);
for (Object v : values.getValues()) {
T value = converter.apply(v);
retval = (value.compareTo(retval) < 0) ? value : retval;
}
return retval;
}
}
public void testSimpleSorts() throws Exception {
Random random = random();
assertAcked(prepareCreate("test")
.addMapping("type1", jsonBuilder()
.startObject()
.startObject("type1")
.startObject("properties")
.startObject("str_value")
.field("type", "keyword")
.endObject()
.startObject("boolean_value")
.field("type", "boolean")
.endObject()
.startObject("byte_value")
.field("type", "byte")
.endObject()
.startObject("short_value")
.field("type", "short")
.endObject()
.startObject("integer_value")
.field("type", "integer")
.endObject()
.startObject("long_value")
.field("type", "long")
.endObject()
.startObject("float_value")
.field("type", "float")
.endObject()
.startObject("double_value")
.field("type", "double")
.endObject()
.endObject()
.endObject()
.endObject()));
ensureGreen();
List<IndexRequestBuilder> builders = new ArrayList<>();
for (int i = 0; i < 10; i++) {
builders.add(client().prepareIndex("test", "type1", Integer.toString(i))
.setSource(jsonBuilder()
.startObject()
.field("str_value", new String(new char[]{(char) (97 + i), (char) (97 + i)}))
.field("boolean_value", true)
.field("byte_value", i)
.field("short_value", i)
.field("integer_value", i)
.field("long_value", i)
.field("float_value", 0.1 * i)
.field("double_value", 0.1 * i)
.endObject()
));
}
Collections.shuffle(builders, random);
for (IndexRequestBuilder builder : builders) {
builder.execute().actionGet();
if (random.nextBoolean()) {
if (random.nextInt(5) != 0) {
refresh();
} else {
client().admin().indices().prepareFlush().get();
}
}
}
refresh();
// STRING script
int size = 1 + random.nextInt(10);
Script script = new Script("doc['str_value'].value", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.setSize(size)
.addSort(new ScriptSortBuilder(script, ScriptSortType.STRING))
.get();
assertHitCount(searchResponse, 10);
assertThat(searchResponse.getHits().hits().length, equalTo(size));
for (int i = 0; i < size; i++) {
SearchHit searchHit = searchResponse.getHits().getAt(i);
assertThat(searchHit.id(), equalTo(Integer.toString(i)));
String expected = new String(new char[]{(char) (97 + i), (char) (97 + i)});
assertThat(searchHit.sortValues()[0].toString(), equalTo(expected));
}
size = 1 + random.nextInt(10);
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.setSize(size)
.addSort("str_value", SortOrder.DESC)
.get();
assertHitCount(searchResponse, 10);
assertThat(searchResponse.getHits().hits().length, equalTo(size));
for (int i = 0; i < size; i++) {
SearchHit searchHit = searchResponse.getHits().getAt(i);
assertThat(searchHit.id(), equalTo(Integer.toString(9 - i)));
String expected = new String(new char[]{(char) (97 + (9 - i)), (char) (97 + (9 - i))});
assertThat(searchHit.sortValues()[0].toString(), equalTo(expected));
}
assertThat(searchResponse.toString(), not(containsString("error")));
assertNoFailures(searchResponse);
}
public void testSortMinValueScript() throws IOException {
String mapping = jsonBuilder()
.startObject()
.startObject("type1")
.startObject("properties")
.startObject("lvalue")
.field("type", "long")
.endObject()
.startObject("dvalue")
.field("type", "double")
.endObject()
.startObject("svalue")
.field("type", "keyword")
.endObject()
.startObject("gvalue")
.field("type", "geo_point")
.endObject()
.endObject()
.endObject()
.endObject().string();
assertAcked(prepareCreate("test").addMapping("type1", mapping));
ensureGreen();
for (int i = 0; i < 10; i++) {
client().prepareIndex("test", "type1", "" + i)
.setSource(jsonBuilder()
.startObject()
.field("ord", i)
.field("svalue", new String[]{"" + i, "" + (i + 1), "" + (i + 2)})
.field("lvalue", new long[]{i, i + 1, i + 2})
.field("dvalue", new double[]{i, i + 1, i + 2})
.startObject("gvalue")
.field("lat", (double) i + 1)
.field("lon", (double) i)
.endObject()
.endObject())
.get();
}
for (int i = 10; i < 20; i++) { // add some docs that don't have values in those fields
client().prepareIndex("test", "type1", "" + i)
.setSource(jsonBuilder()
.startObject()
.field("ord", i)
.endObject())
.get();
}
client().admin().indices().prepareRefresh("test").get();
// test the long values
SearchResponse searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("min", new Script("get min long", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addSort(SortBuilders.fieldSort("ord").order(SortOrder.ASC).unmappedType("long"))
.setSize(10)
.get();
assertNoFailures(searchResponse);
assertHitCount(searchResponse, 20L);
for (int i = 0; i < 10; i++) {
SearchHit searchHit = searchResponse.getHits().getAt(i);
assertThat("res: " + i + " id: " + searchHit.getId(), searchHit.field("min").value(), equalTo((long) i));
}
// test the double values
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("min", new Script("get min double", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addSort(SortBuilders.fieldSort("ord").order(SortOrder.ASC).unmappedType("long"))
.setSize(10)
.get();
assertNoFailures(searchResponse);
assertHitCount(searchResponse, 20L);
for (int i = 0; i < 10; i++) {
SearchHit searchHit = searchResponse.getHits().getAt(i);
assertThat("res: " + i + " id: " + searchHit.getId(), searchHit.field("min").value(), equalTo((double) i));
}
// test the string values
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("min", new Script("get min string", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addSort(SortBuilders.fieldSort("ord").order(SortOrder.ASC).unmappedType("long"))
.setSize(10)
.get();
assertNoFailures(searchResponse);
assertHitCount(searchResponse, 20L);
for (int i = 0; i < 10; i++) {
SearchHit searchHit = searchResponse.getHits().getAt(i);
assertThat("res: " + i + " id: " + searchHit.getId(), searchHit.field("min").value(), equalTo(i));
}
// test the geopoint values
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("min", new Script("get min geopoint lon", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addSort(SortBuilders.fieldSort("ord").order(SortOrder.ASC).unmappedType("long"))
.setSize(10)
.get();
assertNoFailures(searchResponse);
assertHitCount(searchResponse, 20L);
for (int i = 0; i < 10; i++) {
SearchHit searchHit = searchResponse.getHits().getAt(i);
assertThat("res: " + i + " id: " + searchHit.getId(), searchHit.field("min").value(), closeTo(i, GeoUtils.TOLERANCE));
}
}
public void testDocumentsWithNullValue() throws Exception {
// TODO: sort shouldn't fail when sort field is mapped dynamically
// We have to specify mapping explicitly because by the time search is performed dynamic mapping might not
// be propagated to all nodes yet and sort operation fail when the sort field is not defined
String mapping = jsonBuilder()
.startObject()
.startObject("type1")
.startObject("properties")
.startObject("id")
.field("type", "keyword")
.endObject()
.startObject("svalue")
.field("type", "keyword")
.endObject()
.endObject()
.endObject()
.endObject().string();
assertAcked(prepareCreate("test").addMapping("type1", mapping));
ensureGreen();
client().prepareIndex("test", "type1")
.setSource(jsonBuilder().startObject()
.field("id", "1")
.field("svalue", "aaa")
.endObject())
.get();
client().prepareIndex("test", "type1")
.setSource(jsonBuilder().startObject()
.field("id", "2")
.nullField("svalue")
.endObject())
.get();
client().prepareIndex("test", "type1")
.setSource(jsonBuilder().startObject()
.field("id", "3")
.field("svalue", "bbb")
.endObject())
.get();
flush();
refresh();
Script scripField = new Script("doc['id'].value", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("id", scripField)
.addSort("svalue", SortOrder.ASC)
.get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(3L));
assertThat(searchResponse.getHits().getAt(0).field("id").value(), equalTo("1"));
assertThat(searchResponse.getHits().getAt(1).field("id").value(), equalTo("3"));
assertThat(searchResponse.getHits().getAt(2).field("id").value(), equalTo("2"));
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("id", new Script("doc['id'].values[0]", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.addSort("svalue", SortOrder.ASC)
.get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(3L));
assertThat(searchResponse.getHits().getAt(0).field("id").value(), equalTo("1"));
assertThat(searchResponse.getHits().getAt(1).field("id").value(), equalTo("3"));
assertThat(searchResponse.getHits().getAt(2).field("id").value(), equalTo("2"));
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("id", scripField)
.addSort("svalue", SortOrder.DESC)
.get();
if (searchResponse.getFailedShards() > 0) {
logger.warn("Failed shards:");
for (ShardSearchFailure shardSearchFailure : searchResponse.getShardFailures()) {
logger.warn("-> {}", shardSearchFailure);
}
}
assertThat(searchResponse.getFailedShards(), equalTo(0));
assertThat(searchResponse.getHits().getTotalHits(), equalTo(3L));
assertThat(searchResponse.getHits().getAt(0).field("id").value(), equalTo("3"));
assertThat(searchResponse.getHits().getAt(1).field("id").value(), equalTo("1"));
assertThat(searchResponse.getHits().getAt(2).field("id").value(), equalTo("2"));
// a query with docs just with null values
searchResponse = client().prepareSearch()
.setQuery(termQuery("id", "2"))
.addScriptField("id", scripField)
.addSort("svalue", SortOrder.DESC)
.get();
if (searchResponse.getFailedShards() > 0) {
logger.warn("Failed shards:");
for (ShardSearchFailure shardSearchFailure : searchResponse.getShardFailures()) {
logger.warn("-> {}", shardSearchFailure);
}
}
assertThat(searchResponse.getFailedShards(), equalTo(0));
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
assertThat(searchResponse.getHits().getAt(0).field("id").value(), equalTo("2"));
}
public void test2920() throws IOException {
assertAcked(prepareCreate("test")
.addMapping("test", jsonBuilder()
.startObject()
.startObject("test")
.startObject("properties")
.startObject("value")
.field("type", "keyword")
.endObject()
.endObject()
.endObject()
.endObject()));
ensureGreen();
for (int i = 0; i < 10; i++) {
client().prepareIndex("test", "test", Integer.toString(i))
.setSource(jsonBuilder().startObject().field("value", "" + i).endObject()).get();
}
refresh();
Script sortScript = new Script("\u0027\u0027", ScriptType.INLINE, CustomScriptPlugin.NAME, null);
SearchResponse searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addSort(scriptSort(sortScript, ScriptSortType.STRING))
.setSize(10)
.get();
assertNoFailures(searchResponse);
}
}

View File

@ -17,7 +17,7 @@
* under the License.
*/
package org.elasticsearch.messy.tests;
package org.elasticsearch.search.stats;
import org.elasticsearch.action.admin.cluster.node.stats.NodeStats;
import org.elasticsearch.action.admin.cluster.node.stats.NodesStatsResponse;
@ -32,19 +32,22 @@ import org.elasticsearch.common.unit.TimeValue;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.search.stats.SearchStats.Stats;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.search.highlight.HighlightBuilder;
import org.elasticsearch.test.ESIntegTestCase;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_REPLICAS;
import static org.elasticsearch.cluster.metadata.IndexMetaData.SETTING_NUMBER_OF_SHARDS;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.script.ScriptService.ScriptType;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAllSuccessful;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
@ -56,13 +59,23 @@ import static org.hamcrest.Matchers.lessThanOrEqualTo;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
/**
*/
@ESIntegTestCase.ClusterScope(minNumDataNodes = 2)
public class SearchStatsTests extends ESIntegTestCase {
public class SearchStatsIT extends ESIntegTestCase {
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class);
return Collections.singleton(CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
return Collections.singletonMap("_source.field", vars -> {
Map<?, ?> src = (Map) vars.get("_source");
return src.get("field");
});
}
}
@Override
@ -108,7 +121,7 @@ public class SearchStatsTests extends ESIntegTestCase {
SearchResponse searchResponse = internalCluster().coordOnlyNodeClient().prepareSearch()
.setQuery(QueryBuilders.termQuery("field", "value")).setStats("group1", "group2")
.highlighter(new HighlightBuilder().field("field"))
.addScriptField("scrip1", new Script("_source.field"))
.addScriptField("script1", new Script("_source.field", ScriptType.INLINE, CustomScriptPlugin.NAME, null))
.setSize(100)
.execute().actionGet();
assertHitCount(searchResponse, docsTest1 + docsTest2);

View File

@ -1,629 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.messy.tests;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.index.query.functionscore.ScoreFunctionBuilders;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.test.ESIntegTestCase;
import org.hamcrest.Matchers;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.hamcrest.Matchers.equalTo;
public class IndexLookupTests extends ESIntegTestCase {
String includeAllFlag = "_FREQUENCIES | _OFFSETS | _PAYLOADS | _POSITIONS | _CACHE";
String includeAllWithoutRecordFlag = "_FREQUENCIES | _OFFSETS | _PAYLOADS | _POSITIONS ";
private HashMap<String, List<Object>> expectedEndOffsetsArray;
private HashMap<String, List<Object>> expectedPayloadsArray;
private HashMap<String, List<Object>> expectedPositionsArray;
private HashMap<String, List<Object>> emptyArray;
private HashMap<String, List<Object>> expectedStartOffsetsArray;
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class);
}
void initTestData() throws InterruptedException, ExecutionException, IOException {
emptyArray = new HashMap<>();
List<Object> empty1 = new ArrayList<>();
empty1.add(-1);
empty1.add(-1);
emptyArray.put("1", empty1);
List<Object> empty2 = new ArrayList<>();
empty2.add(-1);
empty2.add(-1);
emptyArray.put("2", empty2);
List<Object> empty3 = new ArrayList<>();
empty3.add(-1);
empty3.add(-1);
emptyArray.put("3", empty3);
expectedPositionsArray = new HashMap<>();
List<Object> pos1 = new ArrayList<>();
pos1.add(1);
pos1.add(2);
expectedPositionsArray.put("1", pos1);
List<Object> pos2 = new ArrayList<>();
pos2.add(0);
pos2.add(1);
expectedPositionsArray.put("2", pos2);
List<Object> pos3 = new ArrayList<>();
pos3.add(0);
pos3.add(4);
expectedPositionsArray.put("3", pos3);
expectedPayloadsArray = new HashMap<>();
List<Object> pay1 = new ArrayList<>();
pay1.add(2);
pay1.add(3);
expectedPayloadsArray.put("1", pay1);
List<Object> pay2 = new ArrayList<>();
pay2.add(1);
pay2.add(2);
expectedPayloadsArray.put("2", pay2);
List<Object> pay3 = new ArrayList<>();
pay3.add(1);
pay3.add(-1);
expectedPayloadsArray.put("3", pay3);
/*
* "a|1 b|2 b|3 c|4 d " "b|1 b|2 c|3 d|4 a " "b|1 c|2 d|3 a|4 b "
*/
expectedStartOffsetsArray = new HashMap<>();
List<Object> starts1 = new ArrayList<>();
starts1.add(4);
starts1.add(8);
expectedStartOffsetsArray.put("1", starts1);
List<Object> starts2 = new ArrayList<>();
starts2.add(0);
starts2.add(4);
expectedStartOffsetsArray.put("2", starts2);
List<Object> starts3 = new ArrayList<>();
starts3.add(0);
starts3.add(16);
expectedStartOffsetsArray.put("3", starts3);
expectedEndOffsetsArray = new HashMap<>();
List<Object> ends1 = new ArrayList<>();
ends1.add(7);
ends1.add(11);
expectedEndOffsetsArray.put("1", ends1);
List<Object> ends2 = new ArrayList<>();
ends2.add(3);
ends2.add(7);
expectedEndOffsetsArray.put("2", ends2);
List<Object> ends3 = new ArrayList<>();
ends3.add(3);
ends3.add(17);
expectedEndOffsetsArray.put("3", ends3);
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("int_payload_field").field("type", "text").field("index_options", "offsets")
.field("analyzer", "payload_int").endObject().endObject().endObject().endObject();
assertAcked(prepareCreate("test").addMapping("type1", mapping).setSettings(
Settings.builder()
.put(indexSettings())
.put("index.analysis.analyzer.payload_int.tokenizer", "whitespace")
.putArray("index.analysis.analyzer.payload_int.filter", "delimited_int")
.put("index.analysis.filter.delimited_int.delimiter", "|")
.put("index.analysis.filter.delimited_int.encoding", "int")
.put("index.analysis.filter.delimited_int.type", "delimited_payload_filter")));
indexRandom(true, client().prepareIndex("test", "type1", "1").setSource("int_payload_field", "a|1 b|2 b|3 c|4 d "), client()
.prepareIndex("test", "type1", "2").setSource("int_payload_field", "b|1 b|2 c|3 d|4 a "),
client().prepareIndex("test", "type1", "3").setSource("int_payload_field", "b|1 c|2 d|3 a|4 b "));
ensureGreen();
}
public void testTwoScripts() throws Exception {
initTestData();
// check term frequencies for 'a'
Script scriptFieldScript = new Script("term = _index['int_payload_field']['c']; term.tf()");
scriptFieldScript = new Script("1");
Script scoreScript = new Script("term = _index['int_payload_field']['b']; term.tf()");
Map<String, Object> expectedResultsField = new HashMap<>();
expectedResultsField.put("1", 1);
expectedResultsField.put("2", 1);
expectedResultsField.put("3", 1);
Map<String, Object> expectedResultsScore = new HashMap<>();
expectedResultsScore.put("1", 2f);
expectedResultsScore.put("2", 2f);
expectedResultsScore.put("3", 2f);
checkOnlyFunctionScore(scoreScript, expectedResultsScore, 3);
checkValueInEachDocWithFunctionScore(scriptFieldScript, expectedResultsField, scoreScript, expectedResultsScore, 3);
}
public void testCallWithDifferentFlagsFails() throws Exception {
initTestData();
// should throw an exception, we cannot call with different flags twice
// if the flags of the second call were not included in the first call.
Script script = new Script("term = _index['int_payload_field']['b']; return _index['int_payload_field'].get('b', _POSITIONS).tf();");
try {
client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).addScriptField("tvtest", script).execute().actionGet();
} catch (SearchPhaseExecutionException e) {
assertThat(
"got: " + e.toString(),
e.toString()
.indexOf(
"You must call get with all required flags! Instead of _index['int_payload_field'].get('b', _FREQUENCIES) and _index['int_payload_field'].get('b', _POSITIONS) call _index['int_payload_field'].get('b', _FREQUENCIES | _POSITIONS) once]"),
Matchers.greaterThan(-1));
}
// Should not throw an exception this way round
script = new Script(
"term = _index['int_payload_field'].get('b', _POSITIONS | _FREQUENCIES);return _index['int_payload_field']['b'].tf();");
client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).addScriptField("tvtest", script).execute().actionGet();
}
private void checkOnlyFunctionScore(Script scoreScript, Map<String, Object> expectedScore, int numExpectedDocs) {
SearchResponse sr = client().prepareSearch("test")
.setQuery(QueryBuilders.functionScoreQuery(ScoreFunctionBuilders.scriptFunction(scoreScript))).execute()
.actionGet();
assertHitCount(sr, numExpectedDocs);
for (SearchHit hit : sr.getHits().getHits()) {
assertThat("for doc " + hit.getId(), ((Float) expectedScore.get(hit.getId())).doubleValue(),
Matchers.closeTo(hit.score(), 1.e-4));
}
}
public void testDocumentationExample() throws Exception {
initTestData();
Script script = new Script("term = _index['float_payload_field'].get('b'," + includeAllFlag
+ "); payloadSum=0; for (pos in term) {payloadSum = pos.payloadAsInt(0)}; payloadSum");
// non existing field: sum should be 0
HashMap<String, Object> zeroArray = new HashMap<>();
zeroArray.put("1", 0);
zeroArray.put("2", 0);
zeroArray.put("3", 0);
checkValueInEachDoc(script, zeroArray, 3);
script = new Script("term = _index['int_payload_field'].get('b'," + includeAllFlag
+ "); payloadSum=0; for (pos in term) {payloadSum = payloadSum + pos.payloadAsInt(0)}; payloadSum");
// existing field: sums should be as here:
zeroArray.put("1", 5);
zeroArray.put("2", 3);
zeroArray.put("3", 1);
checkValueInEachDoc(script, zeroArray, 3);
}
public void testIteratorAndRecording() throws Exception {
initTestData();
// call twice with record: should work as expected
Script script = createPositionsArrayScriptIterateTwice("b", includeAllFlag, "position");
checkArrayValsInEachDoc(script, expectedPositionsArray, 3);
script = createPositionsArrayScriptIterateTwice("b", includeAllFlag, "startOffset");
checkArrayValsInEachDoc(script, expectedStartOffsetsArray, 3);
script = createPositionsArrayScriptIterateTwice("b", includeAllFlag, "endOffset");
checkArrayValsInEachDoc(script, expectedEndOffsetsArray, 3);
script = createPositionsArrayScriptIterateTwice("b", includeAllFlag, "payloadAsInt(-1)");
checkArrayValsInEachDoc(script, expectedPayloadsArray, 3);
// no record and get iterator twice: should fail
script = createPositionsArrayScriptIterateTwice("b", includeAllWithoutRecordFlag, "position");
checkExceptions(script);
script = createPositionsArrayScriptIterateTwice("b", includeAllWithoutRecordFlag, "startOffset");
checkExceptions(script);
script = createPositionsArrayScriptIterateTwice("b", includeAllWithoutRecordFlag, "endOffset");
checkExceptions(script);
script = createPositionsArrayScriptIterateTwice("b", includeAllWithoutRecordFlag, "payloadAsInt(-1)");
checkExceptions(script);
// no record and get termObject twice and iterate: should fail
script = createPositionsArrayScriptGetInfoObjectTwice("b", includeAllWithoutRecordFlag, "position");
checkExceptions(script);
script = createPositionsArrayScriptGetInfoObjectTwice("b", includeAllWithoutRecordFlag, "startOffset");
checkExceptions(script);
script = createPositionsArrayScriptGetInfoObjectTwice("b", includeAllWithoutRecordFlag, "endOffset");
checkExceptions(script);
script = createPositionsArrayScriptGetInfoObjectTwice("b", includeAllWithoutRecordFlag, "payloadAsInt(-1)");
checkExceptions(script);
}
private Script createPositionsArrayScriptGetInfoObjectTwice(String term, String flags, String what) {
String script = "term = _index['int_payload_field'].get('" + term + "'," + flags
+ "); array=[]; for (pos in term) {array.add(pos." + what + ")}; _index['int_payload_field'].get('" + term + "',"
+ flags + "); array=[]; for (pos in term) {array.add(pos." + what + ")}";
return new Script(script);
}
private Script createPositionsArrayScriptIterateTwice(String term, String flags, String what) {
String script = "term = _index['int_payload_field'].get('" + term + "'," + flags
+ "); array=[]; for (pos in term) {array.add(pos." + what + ")}; array=[]; for (pos in term) {array.add(pos." + what
+ ")}; array";
return new Script(script);
}
private Script createPositionsArrayScript(String field, String term, String flags, String what) {
String script = "term = _index['" + field + "'].get('" + term + "'," + flags
+ "); array=[]; for (pos in term) {array.add(pos." + what + ")}; array";
return new Script(script);
}
private Script createPositionsArrayScriptDefaultGet(String field, String term, String what) {
String script = "term = _index['" + field + "']['" + term + "']; array=[]; for (pos in term) {array.add(pos." + what
+ ")}; array";
return new Script(script);
}
public void testFlags() throws Exception {
initTestData();
// check default flag
Script script = createPositionsArrayScriptDefaultGet("int_payload_field", "b", "position");
// there should be no positions
/* TODO: the following tests fail with the new postings enum apis because of a bogus assert in BlockDocsEnum
checkArrayValsInEachDoc(script, emptyArray, 3);
script = createPositionsArrayScriptDefaultGet("int_payload_field", "b", "startOffset");
// there should be no offsets
checkArrayValsInEachDoc(script, emptyArray, 3);
script = createPositionsArrayScriptDefaultGet("int_payload_field", "b", "endOffset");
// there should be no offsets
checkArrayValsInEachDoc(script, emptyArray, 3);
script = createPositionsArrayScriptDefaultGet("int_payload_field", "b", "payloadAsInt(-1)");
// there should be no payload
checkArrayValsInEachDoc(script, emptyArray, 3);
// check FLAG_FREQUENCIES flag
script = createPositionsArrayScript("int_payload_field", "b", "_FREQUENCIES", "position");
// there should be no positions
checkArrayValsInEachDoc(script, emptyArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_FREQUENCIES", "startOffset");
// there should be no offsets
checkArrayValsInEachDoc(script, emptyArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_FREQUENCIES", "endOffset");
// there should be no offsets
checkArrayValsInEachDoc(script, emptyArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_FREQUENCIES", "payloadAsInt(-1)");
// there should be no payloads
checkArrayValsInEachDoc(script, emptyArray, 3);*/
// check FLAG_POSITIONS flag
script = createPositionsArrayScript("int_payload_field", "b", "_POSITIONS", "position");
// there should be positions
checkArrayValsInEachDoc(script, expectedPositionsArray, 3);
/* TODO: these tests make a bogus assumption that asking for positions will return only positions
script = createPositionsArrayScript("int_payload_field", "b", "_POSITIONS", "startOffset");
// there should be no offsets
checkArrayValsInEachDoc(script, emptyArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_POSITIONS", "endOffset");
// there should be no offsets
checkArrayValsInEachDoc(script, emptyArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_POSITIONS", "payloadAsInt(-1)");
// there should be no payloads
checkArrayValsInEachDoc(script, emptyArray, 3);*/
// check FLAG_OFFSETS flag
script = createPositionsArrayScript("int_payload_field", "b", "_OFFSETS", "position");
// there should be positions and s forth ...
checkArrayValsInEachDoc(script, expectedPositionsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_OFFSETS", "startOffset");
checkArrayValsInEachDoc(script, expectedStartOffsetsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_OFFSETS", "endOffset");
checkArrayValsInEachDoc(script, expectedEndOffsetsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_OFFSETS", "payloadAsInt(-1)");
checkArrayValsInEachDoc(script, expectedPayloadsArray, 3);
// check FLAG_PAYLOADS flag
script = createPositionsArrayScript("int_payload_field", "b", "_PAYLOADS", "position");
checkArrayValsInEachDoc(script, expectedPositionsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_PAYLOADS", "startOffset");
checkArrayValsInEachDoc(script, expectedStartOffsetsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_PAYLOADS", "endOffset");
checkArrayValsInEachDoc(script, expectedEndOffsetsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", "_PAYLOADS", "payloadAsInt(-1)");
checkArrayValsInEachDoc(script, expectedPayloadsArray, 3);
// check all flags
String allFlags = "_POSITIONS | _OFFSETS | _PAYLOADS";
script = createPositionsArrayScript("int_payload_field", "b", allFlags, "position");
checkArrayValsInEachDoc(script, expectedPositionsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", allFlags, "startOffset");
checkArrayValsInEachDoc(script, expectedStartOffsetsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", allFlags, "endOffset");
checkArrayValsInEachDoc(script, expectedEndOffsetsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", allFlags, "payloadAsInt(-1)");
checkArrayValsInEachDoc(script, expectedPayloadsArray, 3);
// check all flags without record
script = createPositionsArrayScript("int_payload_field", "b", includeAllWithoutRecordFlag, "position");
checkArrayValsInEachDoc(script, expectedPositionsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", includeAllWithoutRecordFlag, "startOffset");
checkArrayValsInEachDoc(script, expectedStartOffsetsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", includeAllWithoutRecordFlag, "endOffset");
checkArrayValsInEachDoc(script, expectedEndOffsetsArray, 3);
script = createPositionsArrayScript("int_payload_field", "b", includeAllWithoutRecordFlag, "payloadAsInt(-1)");
checkArrayValsInEachDoc(script, expectedPayloadsArray, 3);
}
private void checkArrayValsInEachDoc(Script script, HashMap<String, List<Object>> expectedArray, int expectedHitSize) {
SearchResponse sr = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).addScriptField("tvtest", script)
.execute().actionGet();
assertHitCount(sr, expectedHitSize);
int nullCounter = 0;
for (SearchHit hit : sr.getHits().getHits()) {
Object result = hit.getFields().get("tvtest").getValues();
Object expectedResult = expectedArray.get(hit.getId());
assertThat("for doc " + hit.getId(), result, equalTo(expectedResult));
if (expectedResult != null) {
nullCounter++;
}
}
assertThat(nullCounter, equalTo(expectedArray.size()));
}
public void testAllExceptPosAndOffset() throws Exception {
XContentBuilder mapping = XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("float_payload_field").field("type", "text").field("index_options", "offsets").field("term_vector", "no")
.field("analyzer", "payload_float").endObject().startObject("string_payload_field").field("type", "text")
.field("index_options", "offsets").field("term_vector", "no").field("analyzer", "payload_string").endObject()
.startObject("int_payload_field").field("type", "text").field("index_options", "offsets")
.field("analyzer", "payload_int").endObject().endObject().endObject().endObject();
assertAcked(prepareCreate("test").addMapping("type1", mapping).setSettings(
Settings.builder()
.put(indexSettings())
.put("index.analysis.analyzer.payload_float.tokenizer", "whitespace")
.putArray("index.analysis.analyzer.payload_float.filter", "delimited_float")
.put("index.analysis.filter.delimited_float.delimiter", "|")
.put("index.analysis.filter.delimited_float.encoding", "float")
.put("index.analysis.filter.delimited_float.type", "delimited_payload_filter")
.put("index.analysis.analyzer.payload_string.tokenizer", "whitespace")
.putArray("index.analysis.analyzer.payload_string.filter", "delimited_string")
.put("index.analysis.filter.delimited_string.delimiter", "|")
.put("index.analysis.filter.delimited_string.encoding", "identity")
.put("index.analysis.filter.delimited_string.type", "delimited_payload_filter")
.put("index.analysis.analyzer.payload_int.tokenizer", "whitespace")
.putArray("index.analysis.analyzer.payload_int.filter", "delimited_int")
.put("index.analysis.filter.delimited_int.delimiter", "|")
.put("index.analysis.filter.delimited_int.encoding", "int")
.put("index.analysis.filter.delimited_int.type", "delimited_payload_filter")
.put("index.number_of_shards", 1)));
indexRandom(true, client().prepareIndex("test", "type1", "1").setSource("float_payload_field", "a|1 b|2 a|3 b "), client()
.prepareIndex("test", "type1", "2").setSource("string_payload_field", "a|a b|b a|a b "),
client().prepareIndex("test", "type1", "3").setSource("float_payload_field", "a|4 b|5 a|6 b "),
client().prepareIndex("test", "type1", "4").setSource("string_payload_field", "a|b b|a a|b b "),
client().prepareIndex("test", "type1", "5").setSource("float_payload_field", "c "),
client().prepareIndex("test", "type1", "6").setSource("int_payload_field", "c|1"));
// get the number of all docs
Script script = new Script("_index.numDocs()");
checkValueInEachDoc(6, script, 6);
// get the number of docs with field float_payload_field
script = new Script("_index['float_payload_field'].docCount()");
checkValueInEachDoc(3, script, 6);
// corner case: what if the field does not exist?
script = new Script("_index['non_existent_field'].docCount()");
checkValueInEachDoc(0, script, 6);
// get the number of all tokens in all docs
script = new Script("_index['float_payload_field'].sumttf()");
checkValueInEachDoc(9, script, 6);
// corner case get the number of all tokens in all docs for non existent
// field
script = new Script("_index['non_existent_field'].sumttf()");
checkValueInEachDoc(0, script, 6);
// get the sum of doc freqs in all docs
script = new Script("_index['float_payload_field'].sumdf()");
checkValueInEachDoc(5, script, 6);
// get the sum of doc freqs in all docs for non existent field
script = new Script("_index['non_existent_field'].sumdf()");
checkValueInEachDoc(0, script, 6);
// check term frequencies for 'a'
script = new Script("term = _index['float_payload_field']['a']; if (term != null) {term.tf()}");
Map<String, Object> expectedResults = new HashMap<>();
expectedResults.put("1", 2);
expectedResults.put("2", 0);
expectedResults.put("3", 2);
expectedResults.put("4", 0);
expectedResults.put("5", 0);
expectedResults.put("6", 0);
checkValueInEachDoc(script, expectedResults, 6);
expectedResults.clear();
// check doc frequencies for 'c'
script = new Script("term = _index['float_payload_field']['c']; if (term != null) {term.df()}");
expectedResults.put("1", 1L);
expectedResults.put("2", 1L);
expectedResults.put("3", 1L);
expectedResults.put("4", 1L);
expectedResults.put("5", 1L);
expectedResults.put("6", 1L);
checkValueInEachDoc(script, expectedResults, 6);
expectedResults.clear();
// check doc frequencies for term that does not exist
script = new Script("term = _index['float_payload_field']['non_existent_term']; if (term != null) {term.df()}");
expectedResults.put("1", 0L);
expectedResults.put("2", 0L);
expectedResults.put("3", 0L);
expectedResults.put("4", 0L);
expectedResults.put("5", 0L);
expectedResults.put("6", 0L);
checkValueInEachDoc(script, expectedResults, 6);
expectedResults.clear();
// check doc frequencies for term that does not exist
script = new Script("term = _index['non_existent_field']['non_existent_term']; if (term != null) {term.tf()}");
expectedResults.put("1", 0);
expectedResults.put("2", 0);
expectedResults.put("3", 0);
expectedResults.put("4", 0);
expectedResults.put("5", 0);
expectedResults.put("6", 0);
checkValueInEachDoc(script, expectedResults, 6);
expectedResults.clear();
// check total term frequencies for 'a'
script = new Script("term = _index['float_payload_field']['a']; if (term != null) {term.ttf()}");
expectedResults.put("1", 4L);
expectedResults.put("2", 4L);
expectedResults.put("3", 4L);
expectedResults.put("4", 4L);
expectedResults.put("5", 4L);
expectedResults.put("6", 4L);
checkValueInEachDoc(script, expectedResults, 6);
expectedResults.clear();
// check float payload for 'b'
HashMap<String, List<Object>> expectedPayloadsArray = new HashMap<>();
script = createPositionsArrayScript("float_payload_field", "b", includeAllFlag, "payloadAsFloat(-1)");
float missingValue = -1;
List<Object> payloadsFor1 = new ArrayList<>();
payloadsFor1.add(2f);
payloadsFor1.add(missingValue);
expectedPayloadsArray.put("1", payloadsFor1);
List<Object> payloadsFor2 = new ArrayList<>();
payloadsFor2.add(5f);
payloadsFor2.add(missingValue);
expectedPayloadsArray.put("3", payloadsFor2);
expectedPayloadsArray.put("6", new ArrayList<>());
expectedPayloadsArray.put("5", new ArrayList<>());
expectedPayloadsArray.put("4", new ArrayList<>());
expectedPayloadsArray.put("2", new ArrayList<>());
checkArrayValsInEachDoc(script, expectedPayloadsArray, 6);
// check string payload for 'b'
expectedPayloadsArray.clear();
payloadsFor1.clear();
payloadsFor2.clear();
script = createPositionsArrayScript("string_payload_field", "b", includeAllFlag, "payloadAsString()");
payloadsFor1.add("b");
payloadsFor1.add(null);
expectedPayloadsArray.put("2", payloadsFor1);
payloadsFor2.add("a");
payloadsFor2.add(null);
expectedPayloadsArray.put("4", payloadsFor2);
expectedPayloadsArray.put("6", new ArrayList<>());
expectedPayloadsArray.put("5", new ArrayList<>());
expectedPayloadsArray.put("3", new ArrayList<>());
expectedPayloadsArray.put("1", new ArrayList<>());
checkArrayValsInEachDoc(script, expectedPayloadsArray, 6);
// check int payload for 'c'
expectedPayloadsArray.clear();
payloadsFor1.clear();
payloadsFor2.clear();
script = createPositionsArrayScript("int_payload_field", "c", includeAllFlag, "payloadAsInt(-1)");
payloadsFor1 = new ArrayList<>();
payloadsFor1.add(1);
expectedPayloadsArray.put("6", payloadsFor1);
expectedPayloadsArray.put("5", new ArrayList<>());
expectedPayloadsArray.put("4", new ArrayList<>());
expectedPayloadsArray.put("3", new ArrayList<>());
expectedPayloadsArray.put("2", new ArrayList<>());
expectedPayloadsArray.put("1", new ArrayList<>());
checkArrayValsInEachDoc(script, expectedPayloadsArray, 6);
}
private void checkExceptions(Script script) {
try {
SearchResponse sr = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).addScriptField("tvtest", script)
.execute().actionGet();
assertThat(sr.getHits().hits().length, equalTo(0));
ShardSearchFailure[] shardFails = sr.getShardFailures();
for (ShardSearchFailure fail : shardFails) {
assertThat(fail.reason().indexOf("Cannot iterate twice! If you want to iterate more that once, add _CACHE explicitly."),
Matchers.greaterThan(-1));
}
} catch (SearchPhaseExecutionException ex) {
assertThat(
"got " + ex.toString(),
ex.toString().indexOf("Cannot iterate twice! If you want to iterate more that once, add _CACHE explicitly."),
Matchers.greaterThan(-1));
}
}
private void checkValueInEachDocWithFunctionScore(Script fieldScript, Map<String, Object> expectedFieldVals, Script scoreScript,
Map<String, Object> expectedScore, int numExpectedDocs) {
SearchResponse sr = client().prepareSearch("test")
.setQuery(QueryBuilders.functionScoreQuery(ScoreFunctionBuilders.scriptFunction(scoreScript)))
.addScriptField("tvtest", fieldScript).execute().actionGet();
assertHitCount(sr, numExpectedDocs);
for (SearchHit hit : sr.getHits().getHits()) {
Object result = hit.getFields().get("tvtest").getValues().get(0);
Object expectedResult = expectedFieldVals.get(hit.getId());
assertThat("for doc " + hit.getId(), result, equalTo(expectedResult));
assertThat("for doc " + hit.getId(), ((Float) expectedScore.get(hit.getId())).doubleValue(),
Matchers.closeTo(hit.score(), 1.e-4));
}
}
private void checkValueInEachDoc(Script script, Map<String, Object> expectedResults, int numExpectedDocs) {
SearchResponse sr = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).addScriptField("tvtest", script)
.execute().actionGet();
assertHitCount(sr, numExpectedDocs);
for (SearchHit hit : sr.getHits().getHits()) {
Object result = hit.getFields().get("tvtest").getValues().get(0);
Object expectedResult = expectedResults.get(hit.getId());
assertThat("for doc " + hit.getId(), result, equalTo(expectedResult));
}
}
private void checkValueInEachDoc(int value, Script script, int numExpectedDocs) {
SearchResponse sr = client().prepareSearch("test").setQuery(QueryBuilders.matchAllQuery()).addScriptField("tvtest", script)
.execute().actionGet();
assertHitCount(sr, numExpectedDocs);
for (SearchHit hit : sr.getHits().getHits()) {
Object result = hit.getFields().get("tvtest").getValues().get(0);
if (result instanceof Integer) {
assertThat((Integer)result, equalTo(value));
} else if (result instanceof Long) {
assertThat(((Long) result).intValue(), equalTo(value));
} else {
fail();
}
}
}
}

View File

@ -1,334 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.elasticsearch.messy.tests;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.ShardSearchFailure;
import org.elasticsearch.common.geo.GeoUtils;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.groovy.GroovyPlugin;
import org.elasticsearch.search.sort.ScriptSortBuilder;
import org.elasticsearch.search.sort.ScriptSortBuilder.ScriptSortType;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.test.ESIntegTestCase;
import org.elasticsearch.test.InternalSettingsPlugin;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertAcked;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertHitCount;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertNoFailures;
import static org.hamcrest.Matchers.closeTo;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.not;
/**
*
*/
public class SimpleSortTests extends ESIntegTestCase {
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return pluginList(GroovyPlugin.class, InternalSettingsPlugin.class);
}
public void testSimpleSorts() throws Exception {
Random random = random();
assertAcked(prepareCreate("test")
.addMapping("type1", XContentFactory.jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("str_value").field("type", "keyword").endObject()
.startObject("boolean_value").field("type", "boolean").endObject()
.startObject("byte_value").field("type", "byte").endObject()
.startObject("short_value").field("type", "short").endObject()
.startObject("integer_value").field("type", "integer").endObject()
.startObject("long_value").field("type", "long").endObject()
.startObject("float_value").field("type", "float").endObject()
.startObject("double_value").field("type", "double").endObject()
.endObject().endObject().endObject()));
ensureGreen();
List<IndexRequestBuilder> builders = new ArrayList<>();
for (int i = 0; i < 10; i++) {
IndexRequestBuilder builder = client().prepareIndex("test", "type1", Integer.toString(i)).setSource(jsonBuilder().startObject()
.field("str_value", new String(new char[]{(char) (97 + i), (char) (97 + i)}))
.field("boolean_value", true)
.field("byte_value", i)
.field("short_value", i)
.field("integer_value", i)
.field("long_value", i)
.field("float_value", 0.1 * i)
.field("double_value", 0.1 * i)
.endObject());
builders.add(builder);
}
Collections.shuffle(builders, random);
for (IndexRequestBuilder builder : builders) {
builder.execute().actionGet();
if (random.nextBoolean()) {
if (random.nextInt(5) != 0) {
refresh();
} else {
client().admin().indices().prepareFlush().execute().actionGet();
}
}
}
refresh();
// STRING script
int size = 1 + random.nextInt(10);
SearchResponse searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.setSize(size)
.addSort(new ScriptSortBuilder(new Script("doc['str_value'].value"), ScriptSortType.STRING)).execute().actionGet();
assertHitCount(searchResponse, 10);
assertThat(searchResponse.getHits().hits().length, equalTo(size));
for (int i = 0; i < size; i++) {
assertThat(searchResponse.getHits().getAt(i).id(), equalTo(Integer.toString(i)));
assertThat(searchResponse.getHits().getAt(i).sortValues()[0].toString(), equalTo(new String(new char[] { (char) (97 + i),
(char) (97 + i) })));
}
size = 1 + random.nextInt(10);
searchResponse = client().prepareSearch().setQuery(matchAllQuery()).setSize(size).addSort("str_value", SortOrder.DESC).execute()
.actionGet();
assertHitCount(searchResponse, 10);
assertThat(searchResponse.getHits().hits().length, equalTo(size));
for (int i = 0; i < size; i++) {
assertThat(searchResponse.getHits().getAt(i).id(), equalTo(Integer.toString(9 - i)));
assertThat(searchResponse.getHits().getAt(i).sortValues()[0].toString(), equalTo(new String(new char[] { (char) (97 + (9 - i)),
(char) (97 + (9 - i)) })));
}
assertThat(searchResponse.toString(), not(containsString("error")));
assertNoFailures(searchResponse);
}
public void testSortMinValueScript() throws IOException {
String mapping = jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("lvalue").field("type", "long").endObject()
.startObject("dvalue").field("type", "double").endObject()
.startObject("svalue").field("type", "keyword").endObject()
.startObject("gvalue").field("type", "geo_point").endObject()
.endObject().endObject().endObject().string();
assertAcked(prepareCreate("test").addMapping("type1", mapping));
ensureGreen();
for (int i = 0; i < 10; i++) {
IndexRequestBuilder req = client().prepareIndex("test", "type1", "" + i).setSource(jsonBuilder().startObject()
.field("ord", i)
.field("svalue", new String[]{"" + i, "" + (i + 1), "" + (i + 2)})
.field("lvalue", new long[]{i, i + 1, i + 2})
.field("dvalue", new double[]{i, i + 1, i + 2})
.startObject("gvalue")
.field("lat", (double) i + 1)
.field("lon", (double) i)
.endObject()
.endObject());
req.execute().actionGet();
}
for (int i = 10; i < 20; i++) { // add some docs that don't have values in those fields
client().prepareIndex("test", "type1", "" + i).setSource(jsonBuilder().startObject()
.field("ord", i)
.endObject()).execute().actionGet();
}
client().admin().indices().prepareRefresh("test").execute().actionGet();
// test the long values
SearchResponse searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("min", new Script("retval = Long.MAX_VALUE; for (v in doc['lvalue'].values){ retval = min(v, retval) }; retval"))
.addSort(SortBuilders.fieldSort("ord").order(SortOrder.ASC).unmappedType("long")).setSize(10)
.execute().actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(20L));
for (int i = 0; i < 10; i++) {
assertThat("res: " + i + " id: " + searchResponse.getHits().getAt(i).getId(), (Long) searchResponse.getHits().getAt(i).field("min").value(), equalTo((long) i));
}
// test the double values
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("min", new Script("retval = Double.MAX_VALUE; for (v in doc['dvalue'].values){ retval = min(v, retval) }; retval"))
.addSort(SortBuilders.fieldSort("ord").order(SortOrder.ASC).unmappedType("long")).setSize(10)
.execute().actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(20L));
for (int i = 0; i < 10; i++) {
assertThat("res: " + i + " id: " + searchResponse.getHits().getAt(i).getId(), (Double) searchResponse.getHits().getAt(i).field("min").value(), equalTo((double) i));
}
// test the string values
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("min", new Script("retval = Integer.MAX_VALUE; for (v in doc['svalue'].values){ retval = min(Integer.parseInt(v), retval) }; retval"))
.addSort(SortBuilders.fieldSort("ord").order(SortOrder.ASC).unmappedType("long")).setSize(10)
.execute().actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(20L));
for (int i = 0; i < 10; i++) {
assertThat("res: " + i + " id: " + searchResponse.getHits().getAt(i).getId(), (Integer) searchResponse.getHits().getAt(i).field("min").value(), equalTo(i));
}
// test the geopoint values
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("min", new Script("retval = Double.MAX_VALUE; for (v in doc['gvalue'].values){ retval = min(v.lon, retval) }; retval"))
.addSort(SortBuilders.fieldSort("ord").order(SortOrder.ASC).unmappedType("long")).setSize(10)
.execute().actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(20L));
for (int i = 0; i < 10; i++) {
assertThat("res: " + i + " id: " + searchResponse.getHits().getAt(i).getId(), (Double) searchResponse.getHits().getAt(i).field("min").value(), closeTo(i, GeoUtils.TOLERANCE));
}
}
public void testDocumentsWithNullValue() throws Exception {
// TODO: sort shouldn't fail when sort field is mapped dynamically
// We have to specify mapping explicitly because by the time search is performed dynamic mapping might not
// be propagated to all nodes yet and sort operation fail when the sort field is not defined
String mapping = jsonBuilder().startObject().startObject("type1").startObject("properties")
.startObject("id").field("type", "keyword").endObject()
.startObject("svalue").field("type", "keyword").endObject()
.endObject().endObject().endObject().string();
assertAcked(prepareCreate("test").addMapping("type1", mapping));
ensureGreen();
client().prepareIndex("test", "type1").setSource(jsonBuilder().startObject()
.field("id", "1")
.field("svalue", "aaa")
.endObject()).execute().actionGet();
client().prepareIndex("test", "type1").setSource(jsonBuilder().startObject()
.field("id", "2")
.nullField("svalue")
.endObject()).execute().actionGet();
client().prepareIndex("test", "type1").setSource(jsonBuilder().startObject()
.field("id", "3")
.field("svalue", "bbb")
.endObject()).execute().actionGet();
flush();
refresh();
SearchResponse searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("id", new Script("doc['id'].value"))
.addSort("svalue", SortOrder.ASC)
.execute().actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(3L));
assertThat(searchResponse.getHits().getAt(0).field("id").value(), equalTo("1"));
assertThat(searchResponse.getHits().getAt(1).field("id").value(), equalTo("3"));
assertThat(searchResponse.getHits().getAt(2).field("id").value(), equalTo("2"));
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("id", new Script("doc['id'].values[0]"))
.addSort("svalue", SortOrder.ASC)
.execute().actionGet();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits(), equalTo(3L));
assertThat(searchResponse.getHits().getAt(0).field("id").value(), equalTo("1"));
assertThat(searchResponse.getHits().getAt(1).field("id").value(), equalTo("3"));
assertThat(searchResponse.getHits().getAt(2).field("id").value(), equalTo("2"));
searchResponse = client().prepareSearch()
.setQuery(matchAllQuery())
.addScriptField("id", new Script("doc['id'].value"))
.addSort("svalue", SortOrder.DESC)
.execute().actionGet();
if (searchResponse.getFailedShards() > 0) {
logger.warn("Failed shards:");
for (ShardSearchFailure shardSearchFailure : searchResponse.getShardFailures()) {
logger.warn("-> {}", shardSearchFailure);
}
}
assertThat(searchResponse.getFailedShards(), equalTo(0));
assertThat(searchResponse.getHits().getTotalHits(), equalTo(3L));
assertThat(searchResponse.getHits().getAt(0).field("id").value(), equalTo("3"));
assertThat(searchResponse.getHits().getAt(1).field("id").value(), equalTo("1"));
assertThat(searchResponse.getHits().getAt(2).field("id").value(), equalTo("2"));
// a query with docs just with null values
searchResponse = client().prepareSearch()
.setQuery(termQuery("id", "2"))
.addScriptField("id", new Script("doc['id'].value"))
.addSort("svalue", SortOrder.DESC)
.execute().actionGet();
if (searchResponse.getFailedShards() > 0) {
logger.warn("Failed shards:");
for (ShardSearchFailure shardSearchFailure : searchResponse.getShardFailures()) {
logger.warn("-> {}", shardSearchFailure);
}
}
assertThat(searchResponse.getFailedShards(), equalTo(0));
assertThat(searchResponse.getHits().getTotalHits(), equalTo(1L));
assertThat(searchResponse.getHits().getAt(0).field("id").value(), equalTo("2"));
}
public void test2920() throws IOException {
assertAcked(prepareCreate("test").addMapping(
"test",
jsonBuilder().startObject().startObject("test").startObject("properties").startObject("value").field("type", "keyword")
.endObject().endObject().endObject().endObject()));
ensureGreen();
for (int i = 0; i < 10; i++) {
client().prepareIndex("test", "test", Integer.toString(i))
.setSource(jsonBuilder().startObject().field("value", "" + i).endObject()).execute().actionGet();
}
refresh();
SearchResponse searchResponse = client().prepareSearch().setQuery(matchAllQuery())
.addSort(SortBuilders.scriptSort(new Script("\u0027\u0027"), ScriptSortType.STRING)).setSize(10).execute().actionGet();
assertNoFailures(searchResponse);
}
}

View File

@ -1,75 +0,0 @@
/*
* Licensed to Elasticsearch under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
/**
* This package contains tests that use groovy to test what looks
* to be unrelated functionality, or functionality that should be
* tested with a mock instead. Instead of doing an epic battle
* with these tests, they are temporarily moved here to the groovy
* plugin's tests, but that is likely not where they belong. Please
* help by cleaning them up and we can remove this package!
*
* <ul>
* <li>If the test is actually testing groovy specifically, move to
* the org.elasticsearch.script.groovy tests package of this plugin</li>
* <li>If the test is testing scripting integration with another core subsystem,
* fix it to use a mock instead, so it can be in the core tests again</li>
* <li>If the test is just being lazy, and does not really need scripting to test
* something, clean it up!</li>
* </ul>
*/
/* List of renames that took place:
renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/AvgIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/AvgTests.java
renamed: core/src/test/java/org/elasticsearch/document/BulkIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/BulkTests.java
renamed: core/src/test/java/org/elasticsearch/search/child/ChildQuerySearchIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ChildQuerySearchTests.java
renamed: core/src/test/java/org/elasticsearch/transport/ContextAndHeaderTransportIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ContextAndHeaderTransportTests.java
^^^^^ note: the methods from this test using mustache were moved to the mustache module under its messy tests package.
renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/DateHistogramIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/DateHistogramTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/DateRangeIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/DateRangeTests.java
renamed: core/src/test/java/org/elasticsearch/search/functionscore/FunctionScoreIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/FunctionScoreTests.java
renamed: core/src/test/java/org/elasticsearch/search/geo/GeoDistanceIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/GeoDistanceTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/IPv4RangeIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IPv4RangeTests.java
renamed: core/src/test/java/org/elasticsearch/script/IndexLookupIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IndexLookupTests.java
renamed: core/src/test/java/org/elasticsearch/script/IndexedScriptIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/IndexedScriptTests.java
renamed: core/src/test/java/org/elasticsearch/search/innerhits/InnerHitsIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/InnerHitsTests.java
renamed: core/src/test/java/org/elasticsearch/percolator/PercolatorIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/PercolatorTests.java
renamed: core/src/test/java/org/elasticsearch/search/functionscore/RandomScoreFunctionIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/RandomScoreFunctionTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/RangeIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/RangeTests.java
renamed: core/src/test/java/org/elasticsearch/search/scriptfilter/ScriptQuerySearchIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptQuerySearchTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/ScriptedMetricIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/ScriptedMetricTests.java
renamed: core/src/test/java/org/elasticsearch/search/fields/SearchFieldsIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchFieldsTests.java
renamed: core/src/test/java/org/elasticsearch/search/stats/SearchStatsIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchStatsTests.java
renamed: core/src/test/java/org/elasticsearch/search/timeout/SearchTimeoutIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SearchTimeoutTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/SignificantTermsSignificanceScoreIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SignificantTermsSignificanceScoreTests.java
renamed: core/src/test/java/org/elasticsearch/nested/SimpleNestedIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SimpleNestedTests.java
renamed: core/src/test/java/org/elasticsearch/search/sort/SimpleSortIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SimpleSortTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/metrics/SumIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/SumTests.java
renamed: core/src/test/java/org/elasticsearch/search/aggregations/bucket/TopHitsIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/TopHitsTests.java
renamed: core/src/test/java/org/elasticsearch/index/mapper/TransformOnIndexMapperIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/messy/tests/TransformOnIndexMapperTests.java
renamed: core/src/main/java/org/elasticsearch/script/groovy/GroovyScriptCompilationException.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyRestIT.java
renamed: core/src/test/java/org/elasticsearch/script/GroovyScriptIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovyScriptTests.java
renamed: core/src/test/java/org/elasticsearch/script/GroovySecurityIT.java -> plugins/lang-groovy/src/test/java/org/elasticsearch/script/groovy/GroovySecurityTests.java
renamed: core/src/test/resources/org/elasticsearch/search/aggregations/metrics/scripted/conf/scripts/combine_script.groovy -> plugins/lang-groovy/src/test/resources/org/elasticsearch/messy/tests/conf/scripts/combine_script.groovy
renamed: core/src/test/resources/org/elasticsearch/search/aggregations/metrics/scripted/conf/scripts/init_script.groovy -> plugins/lang-groovy/src/test/resources/org/elasticsearch/messy/tests/conf/scripts/init_script.groovy
renamed: core/src/test/resources/org/elasticsearch/search/aggregations/metrics/scripted/conf/scripts/map_script.groovy -> plugins/lang-groovy/src/test/resources/org/elasticsearch/messy/tests/conf/scripts/map_script.groovy
renamed: core/src/test/resources/org/elasticsearch/search/aggregations/metrics/scripted/conf/scripts/reduce_script.groovy -> plugins/lang-groovy/src/test/resources/org/elasticsearch/messy/tests/conf/scripts/reduce_script.groovy
renamed: core/src/test/resources/org/elasticsearch/search/aggregations/bucket/config/scripts/significance_script_no_params.groovy -> plugins/lang-groovy/src/test/resources/org/elasticsearch/messy/tests/conf/scripts/significance_script_no_params.groovy
renamed: core/src/test/resources/org/elasticsearch/search/aggregations/bucket/config/scripts/significance_script_with_params.groovy -> plugins/lang-groovy/src/test/resources/org/elasticsearch/messy/tests/conf/scripts/significance_script_with_params.groovy
*/
package org.elasticsearch.messy.tests;

View File

@ -18,7 +18,7 @@
*/
package org.elasticsearch.messy.tests;
package org.elasticsearch.script.groovy;
import org.elasticsearch.ExceptionsHelper;
import org.elasticsearch.action.index.IndexRequestBuilder;
@ -51,7 +51,7 @@ import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.notNullValue;
public class IndexedScriptTests extends ESIntegTestCase {
public class GroovyIndexedScriptTests extends ESIntegTestCase {
@Override
protected Collection<Class<? extends Plugin>> nodePlugins() {
return Collections.singleton(GroovyPlugin.class);

View File

@ -1 +0,0 @@
newaggregation = []; sum = 0;for (a in _agg) { sum += a}; newaggregation.add(sum); return newaggregation

View File

@ -1 +0,0 @@
newaggregation = []; sum = 0;for (aggregation in _aggs) { for (a in aggregation) { sum += a} }; newaggregation.add(sum); return newaggregation

View File

@ -1 +0,0 @@
return _subset_freq + _subset_size + _superset_freq + _superset_size

View File

@ -1 +0,0 @@
return param*(_subset_freq + _subset_size + _superset_freq + _superset_size)/param

View File

@ -23,6 +23,7 @@ import org.apache.lucene.index.memory.MemoryIndex;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.common.xcontent.XContentFactory;
import org.elasticsearch.common.xcontent.XContentType;
@ -33,16 +34,19 @@ import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryShardContext;
import org.elasticsearch.index.query.TermQueryBuilder;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.script.MockScriptPlugin;
import org.elasticsearch.script.Script;
import org.elasticsearch.script.ScriptService.ScriptType;
import org.elasticsearch.test.AbstractQueryTestCase;
import org.junit.Before;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
public class TemplateQueryBuilderTests extends AbstractQueryTestCase<TemplateQueryBuilder> {
@ -53,7 +57,39 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase<TemplateQue
@Override
protected Collection<Class<? extends Plugin>> getPlugins() {
return Collections.singleton(MustachePlugin.class);
return Arrays.asList(MustachePlugin.class, CustomScriptPlugin.class);
}
public static class CustomScriptPlugin extends MockScriptPlugin {
@Override
@SuppressWarnings("unchecked")
protected Map<String, Function<Map<String, Object>, Object>> pluginScripts() {
Map<String, Function<Map<String, Object>, Object>> scripts = new HashMap<>();
scripts.put("{ \"match_all\" : {}}",
s -> new BytesArray("{ \"match_all\" : {}}"));
scripts.put("{ \"match_all\" : {\"_name\" : \"foobar\"}}",
s -> new BytesArray("{ \"match_all\" : {\"_name\" : \"foobar\"}}"));
scripts.put("{\n" +
" \"term\" : {\n" +
" \"foo\" : {\n" +
" \"value\" : \"bar\",\n" +
" \"boost\" : 2.0\n" +
" }\n" +
" }\n" +
"}", s -> new BytesArray("{\n" +
" \"term\" : {\n" +
" \"foo\" : {\n" +
" \"value\" : \"bar\",\n" +
" \"boost\" : 2.0\n" +
" }\n" +
" }\n" +
"}"));
return scripts;
}
}
@Before
@ -68,7 +104,7 @@ public class TemplateQueryBuilderTests extends AbstractQueryTestCase<TemplateQue
@Override
protected TemplateQueryBuilder doCreateTestQueryBuilder() {
return new TemplateQueryBuilder(new Script(templateBase.toString(), ScriptType.INLINE, "mockscript", null, null));
return new TemplateQueryBuilder(new Script(templateBase.toString(), ScriptType.INLINE, "mustache", null, null));
}
@Override

View File

@ -34,6 +34,15 @@ import java.util.function.Function;
/**
* A mocked script engine that can be used for testing purpose.
*
* This script engine allows to define a set of predefined scripts that basically a combination of a key and a
* function:
*
* The key can be anything as long as it is a {@link String} and is used to resolve the scripts
* at compilation time. For inline scripts, the key can be a description of the script. For stored and file scripts,
* the source must match a key in the predefined set of scripts.
*
* The function is used to provide the result of the script execution and can return anything.
*/
public class MockScriptEngine implements ScriptEngineService {
@ -63,7 +72,13 @@ public class MockScriptEngine implements ScriptEngineService {
@Override
public Object compile(String name, String source, Map<String, String> params) {
// Scripts are always resolved using the script's source. For inline scripts, it's easy because they don't have names and the
// source is always provided. For stored and file scripts, the source of the script must match the key of a predefined script.
Function<Map<String, Object>, Object> script = scripts.get(source);
if (script == null) {
throw new IllegalArgumentException("No pre defined script matching [" + source + "] for script with name [" + name + "], " +
"did you declare the mocked script?");
}
return new MockCompiledScript(name, params, source, script);
}

View File

@ -21,7 +21,6 @@ package org.elasticsearch.test;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.io.JsonStringEncoder;
import org.apache.lucene.search.BoostQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
@ -94,6 +93,7 @@ import org.elasticsearch.node.internal.InternalSettingsPreparer;
import org.elasticsearch.plugins.MapperPlugin;
import org.elasticsearch.plugins.Plugin;
import org.elasticsearch.plugins.PluginsService;
import org.elasticsearch.plugins.ScriptPlugin;
import org.elasticsearch.plugins.SearchPlugin;
import org.elasticsearch.script.ScriptModule;
import org.elasticsearch.script.ScriptService;
@ -861,7 +861,7 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
new Class[]{Client.class},
clientInvocationHandler);
NamedWriteableRegistry namedWriteableRegistry = new NamedWriteableRegistry();
ScriptModule scriptModule = newTestScriptModule();
ScriptModule scriptModule = createScriptModule(pluginsService.filterPlugins(ScriptPlugin.class));
List<Setting<?>> scriptSettings = scriptModule.getSettings();
scriptSettings.addAll(pluginsService.getPluginSettings());
scriptSettings.add(InternalSettingsPlugin.VERSION_CREATED);
@ -970,6 +970,20 @@ public abstract class AbstractQueryTestCase<QB extends AbstractQueryBuilder<QB>>
scriptService, indicesQueriesRegistry, client, null, state);
}
ScriptModule createScriptModule(List<ScriptPlugin> scriptPlugins) {
if (scriptPlugins == null || scriptPlugins.isEmpty()) {
return newTestScriptModule();
}
Settings settings = Settings.builder()
.put(Environment.PATH_HOME_SETTING.getKey(), createTempDir())
// no file watching, so we don't need a ResourceWatcherService
.put(ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING.getKey(), false)
.build();
Environment environment = new Environment(settings);
return ScriptModule.create(settings, environment, null, scriptPlugins);
}
}
}

View File

@ -835,7 +835,8 @@ public abstract class ESTestCase extends LuceneTestCase {
.put(ScriptService.SCRIPT_AUTO_RELOAD_ENABLED_SETTING.getKey(), false)
.build();
Environment environment = new Environment(settings);
return new ScriptModule(settings, environment, null, singletonList(new MockScriptEngine()), emptyList());
MockScriptEngine scriptEngine = new MockScriptEngine(MockScriptEngine.NAME, Collections.singletonMap("1", script -> "1"));
return new ScriptModule(settings, environment, null, singletonList(scriptEngine), emptyList());
}
/** Creates an IndicesModule for testing with the given mappers and metadata mappers. */