Use `typed_keys` parameter to prefix suggester names by type in search responses (#23080)
This pull request reuses the typed_keys parameter added in #22965, but this time it applies it to suggesters. When set to true, the suggester names in the search response will be prefixed with a prefix that reflects their type.
This commit is contained in:
parent
63ea6f7168
commit
e2e5937455
|
@ -52,7 +52,7 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
|
|
||||||
public class RestMultiSearchAction extends BaseRestHandler {
|
public class RestMultiSearchAction extends BaseRestHandler {
|
||||||
|
|
||||||
private static final Set<String> RESPONSE_PARAMS = Collections.singleton("typed_keys");
|
private static final Set<String> RESPONSE_PARAMS = Collections.singleton(RestSearchAction.TYPED_KEYS_PARAM);
|
||||||
|
|
||||||
private final boolean allowExplicitIndex;
|
private final boolean allowExplicitIndex;
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,8 @@ import static org.elasticsearch.search.suggest.SuggestBuilders.termSuggestion;
|
||||||
|
|
||||||
public class RestSearchAction extends BaseRestHandler {
|
public class RestSearchAction extends BaseRestHandler {
|
||||||
|
|
||||||
private static final Set<String> RESPONSE_PARAMS = Collections.singleton("typed_keys");
|
public static final String TYPED_KEYS_PARAM = "typed_keys";
|
||||||
|
private static final Set<String> RESPONSE_PARAMS = Collections.singleton(TYPED_KEYS_PARAM);
|
||||||
|
|
||||||
public RestSearchAction(Settings settings, RestController controller) {
|
public RestSearchAction(Settings settings, RestController controller) {
|
||||||
super(settings);
|
super(settings);
|
||||||
|
|
|
@ -25,6 +25,7 @@ import org.elasticsearch.common.io.stream.StreamOutput;
|
||||||
import org.elasticsearch.common.util.BigArrays;
|
import org.elasticsearch.common.util.BigArrays;
|
||||||
import org.elasticsearch.common.xcontent.ToXContent;
|
import org.elasticsearch.common.xcontent.ToXContent;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
|
import org.elasticsearch.rest.action.search.RestSearchAction;
|
||||||
import org.elasticsearch.script.ScriptService;
|
import org.elasticsearch.script.ScriptService;
|
||||||
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
import org.elasticsearch.search.aggregations.pipeline.PipelineAggregator;
|
||||||
import org.elasticsearch.search.aggregations.support.AggregationPath;
|
import org.elasticsearch.search.aggregations.support.AggregationPath;
|
||||||
|
@ -164,9 +165,12 @@ public abstract class InternalAggregation implements Aggregation, ToXContent, Na
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public final XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
// Concatenates the type and the name of the aggregation (ex: top_hits#foo)
|
if (params.paramAsBoolean(RestSearchAction.TYPED_KEYS_PARAM, false)) {
|
||||||
String name = params.paramAsBoolean("typed_keys", false) ? String.join(TYPED_KEYS_DELIMITER, getType(), getName()) : getName();
|
// Concatenates the type and the name of the aggregation (ex: top_hits#foo)
|
||||||
builder.startObject(name);
|
builder.startObject(String.join(TYPED_KEYS_DELIMITER, getType(), getName()));
|
||||||
|
} else {
|
||||||
|
builder.startObject(getName());
|
||||||
|
}
|
||||||
if (this.metaData != null) {
|
if (this.metaData != null) {
|
||||||
builder.field(CommonFields.META);
|
builder.field(CommonFields.META);
|
||||||
builder.map(this.metaData);
|
builder.map(this.metaData);
|
||||||
|
|
|
@ -30,6 +30,8 @@ import org.elasticsearch.common.xcontent.ToXContentObject;
|
||||||
import org.elasticsearch.common.xcontent.XContentBuilder;
|
import org.elasticsearch.common.xcontent.XContentBuilder;
|
||||||
import org.elasticsearch.common.xcontent.XContentFactory;
|
import org.elasticsearch.common.xcontent.XContentFactory;
|
||||||
import org.elasticsearch.common.xcontent.XContentParser;
|
import org.elasticsearch.common.xcontent.XContentParser;
|
||||||
|
import org.elasticsearch.rest.action.search.RestSearchAction;
|
||||||
|
import org.elasticsearch.search.aggregations.InternalAggregation;
|
||||||
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry;
|
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry;
|
||||||
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry.Option;
|
import org.elasticsearch.search.suggest.Suggest.Suggestion.Entry.Option;
|
||||||
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
|
import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
|
||||||
|
@ -149,7 +151,7 @@ public class Suggest implements Iterable<Suggest.Suggestion<? extends Entry<? ex
|
||||||
public void writeTo(StreamOutput out) throws IOException {
|
public void writeTo(StreamOutput out) throws IOException {
|
||||||
out.writeVInt(suggestions.size());
|
out.writeVInt(suggestions.size());
|
||||||
for (Suggestion<?> command : suggestions) {
|
for (Suggestion<?> command : suggestions) {
|
||||||
out.writeVInt(command.getType());
|
out.writeVInt(command.getWriteableType());
|
||||||
command.writeTo(out);
|
command.writeTo(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -206,6 +208,8 @@ public class Suggest implements Iterable<Suggest.Suggestion<? extends Entry<? ex
|
||||||
*/
|
*/
|
||||||
public static class Suggestion<T extends Suggestion.Entry> implements Iterable<T>, Streamable, ToXContent {
|
public static class Suggestion<T extends Suggestion.Entry> implements Iterable<T>, Streamable, ToXContent {
|
||||||
|
|
||||||
|
private static final String NAME = "suggestion";
|
||||||
|
|
||||||
public static final int TYPE = 0;
|
public static final int TYPE = 0;
|
||||||
protected String name;
|
protected String name;
|
||||||
protected int size;
|
protected int size;
|
||||||
|
@ -223,10 +227,23 @@ public class Suggest implements Iterable<Suggest.Suggestion<? extends Entry<? ex
|
||||||
entries.add(entry);
|
entries.add(entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getType() {
|
/**
|
||||||
|
* Returns a integer representing the type of the suggestion. This is used for
|
||||||
|
* internal serialization over the network.
|
||||||
|
*/
|
||||||
|
public int getWriteableType() { // TODO remove this in favor of NamedWriteable
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a string representing the type of the suggestion. This type is added to
|
||||||
|
* the suggestion name in the XContent response, so that it can later be used by
|
||||||
|
* REST clients to determine the internal type of the suggestion.
|
||||||
|
*/
|
||||||
|
protected String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Iterator<T> iterator() {
|
public Iterator<T> iterator() {
|
||||||
return entries.iterator();
|
return entries.iterator();
|
||||||
|
@ -338,7 +355,12 @@ public class Suggest implements Iterable<Suggest.Suggestion<? extends Entry<? ex
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startArray(name);
|
if (params.paramAsBoolean(RestSearchAction.TYPED_KEYS_PARAM, false)) {
|
||||||
|
// Concatenates the type and the name of the suggestion (ex: completion#foo)
|
||||||
|
builder.startArray(String.join(InternalAggregation.TYPED_KEYS_DELIMITER, getType(), getName()));
|
||||||
|
} else {
|
||||||
|
builder.startArray(getName());
|
||||||
|
}
|
||||||
for (Entry<?> entry : entries) {
|
for (Entry<?> entry : entries) {
|
||||||
entry.toXContent(builder, params);
|
entry.toXContent(builder, params);
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,6 +57,8 @@ import static org.elasticsearch.search.suggest.Suggest.COMPARATOR;
|
||||||
*/
|
*/
|
||||||
public final class CompletionSuggestion extends Suggest.Suggestion<CompletionSuggestion.Entry> {
|
public final class CompletionSuggestion extends Suggest.Suggestion<CompletionSuggestion.Entry> {
|
||||||
|
|
||||||
|
private static final String NAME = "completion";
|
||||||
|
|
||||||
public static final int TYPE = 4;
|
public static final int TYPE = 4;
|
||||||
|
|
||||||
public CompletionSuggestion() {
|
public CompletionSuggestion() {
|
||||||
|
@ -165,10 +167,15 @@ public final class CompletionSuggestion extends Suggest.Suggestion<CompletionSug
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getType() {
|
public int getWriteableType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Entry newEntry() {
|
protected Entry newEntry() {
|
||||||
return new Entry();
|
return new Entry();
|
||||||
|
|
|
@ -31,6 +31,8 @@ import java.io.IOException;
|
||||||
* Suggestion entry returned from the {@link PhraseSuggester}.
|
* Suggestion entry returned from the {@link PhraseSuggester}.
|
||||||
*/
|
*/
|
||||||
public class PhraseSuggestion extends Suggest.Suggestion<PhraseSuggestion.Entry> {
|
public class PhraseSuggestion extends Suggest.Suggestion<PhraseSuggestion.Entry> {
|
||||||
|
|
||||||
|
private static final String NAME = "phrase";
|
||||||
public static final int TYPE = 3;
|
public static final int TYPE = 3;
|
||||||
|
|
||||||
public PhraseSuggestion() {
|
public PhraseSuggestion() {
|
||||||
|
@ -41,10 +43,15 @@ public class PhraseSuggestion extends Suggest.Suggestion<PhraseSuggestion.Entry>
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getType() {
|
public int getWriteableType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Entry newEntry() {
|
protected Entry newEntry() {
|
||||||
return new Entry();
|
return new Entry();
|
||||||
|
|
|
@ -40,6 +40,8 @@ import static org.elasticsearch.common.xcontent.ConstructingObjectParser.constru
|
||||||
*/
|
*/
|
||||||
public class TermSuggestion extends Suggestion<TermSuggestion.Entry> {
|
public class TermSuggestion extends Suggestion<TermSuggestion.Entry> {
|
||||||
|
|
||||||
|
private static final String NAME = "term";
|
||||||
|
|
||||||
public static final Comparator<Suggestion.Entry.Option> SCORE = new Score();
|
public static final Comparator<Suggestion.Entry.Option> SCORE = new Score();
|
||||||
public static final Comparator<Suggestion.Entry.Option> FREQUENCY = new Frequency();
|
public static final Comparator<Suggestion.Entry.Option> FREQUENCY = new Frequency();
|
||||||
public static final int TYPE = 1;
|
public static final int TYPE = 1;
|
||||||
|
@ -96,10 +98,15 @@ public class TermSuggestion extends Suggestion<TermSuggestion.Entry> {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getType() {
|
public int getWriteableType() {
|
||||||
return TYPE;
|
return TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String getType() {
|
||||||
|
return NAME;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Comparator<Option> sortComparator() {
|
protected Comparator<Option> sortComparator() {
|
||||||
switch (sort) {
|
switch (sort) {
|
||||||
|
|
|
@ -118,8 +118,8 @@ GET /twitter/tweet/_search?typed_keys
|
||||||
// CONSOLE
|
// CONSOLE
|
||||||
// TEST[setup:twitter]
|
// TEST[setup:twitter]
|
||||||
|
|
||||||
In the response, the aggregations names will be changed to respectively `date_histogram:tweets_over_time` and
|
In the response, the aggregations names will be changed to respectively `date_histogram#tweets_over_time` and
|
||||||
`top_hits:top_users`, reflecting the internal types of each aggregation:
|
`top_hits#top_users`, reflecting the internal types of each aggregation:
|
||||||
|
|
||||||
[source,js]
|
[source,js]
|
||||||
--------------------------------------------------
|
--------------------------------------------------
|
||||||
|
|
|
@ -147,3 +147,5 @@ include::suggesters/phrase-suggest.asciidoc[]
|
||||||
include::suggesters/completion-suggest.asciidoc[]
|
include::suggesters/completion-suggest.asciidoc[]
|
||||||
|
|
||||||
include::suggesters/context-suggest.asciidoc[]
|
include::suggesters/context-suggest.asciidoc[]
|
||||||
|
|
||||||
|
include::suggesters/misc.asciidoc[]
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
[[returning-suggesters-type]]
|
||||||
|
=== Returning the type of the suggester
|
||||||
|
|
||||||
|
Sometimes you need to know the exact type of a suggester in order to parse its results. The `typed_keys` parameter
|
||||||
|
can be used to change the suggester's name in the response so that it will be prefixed by its type.
|
||||||
|
|
||||||
|
Considering the following example with two suggesters `term` and `phrase`:
|
||||||
|
|
||||||
|
[source,js]
|
||||||
|
--------------------------------------------------
|
||||||
|
POST _search?typed_keys
|
||||||
|
{
|
||||||
|
"suggest": {
|
||||||
|
"text" : "some test mssage",
|
||||||
|
"my-first-suggester" : {
|
||||||
|
"term" : {
|
||||||
|
"field" : "message"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"my-second-suggester" : {
|
||||||
|
"phrase" : {
|
||||||
|
"field" : "message"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--------------------------------------------------
|
||||||
|
// CONSOLE
|
||||||
|
// TEST[setup:twitter]
|
||||||
|
|
||||||
|
In the response, the suggester names will be changed to respectively `term#my-first-suggester` and
|
||||||
|
`phrase#my-second-suggester`, reflecting the types of each suggestion:
|
||||||
|
|
||||||
|
[source,js]
|
||||||
|
--------------------------------------------------
|
||||||
|
{
|
||||||
|
"suggest": {
|
||||||
|
"term#my-first-suggester": [ <1>
|
||||||
|
{
|
||||||
|
"text": "some",
|
||||||
|
"offset": 0,
|
||||||
|
"length": 4,
|
||||||
|
"options": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "test",
|
||||||
|
"offset": 5,
|
||||||
|
"length": 4,
|
||||||
|
"options": []
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"text": "mssage",
|
||||||
|
"offset": 10,
|
||||||
|
"length": 6,
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "message",
|
||||||
|
"score": 0.8333333,
|
||||||
|
"freq": 4
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"phrase#my-second-suggester": [ <2>
|
||||||
|
{
|
||||||
|
"text": "some test mssage",
|
||||||
|
"offset": 0,
|
||||||
|
"length": 16,
|
||||||
|
"options": [
|
||||||
|
{
|
||||||
|
"text": "some test message",
|
||||||
|
"score": 0.030227963
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
...
|
||||||
|
}
|
||||||
|
--------------------------------------------------
|
||||||
|
// TESTRESPONSE[s/\.\.\./"took": "$body.took", "timed_out": false, "_shards": "$body._shards", "hits": "$body.hits"/]
|
||||||
|
|
||||||
|
<1> The name `my-first-suggester` now contains the `term` prefix.
|
||||||
|
<2> The name `my-second-suggester` now contains the `phrase` prefix.
|
|
@ -28,6 +28,7 @@ import org.elasticsearch.rest.RestController;
|
||||||
import org.elasticsearch.rest.RestRequest;
|
import org.elasticsearch.rest.RestRequest;
|
||||||
import org.elasticsearch.rest.action.RestToXContentListener;
|
import org.elasticsearch.rest.action.RestToXContentListener;
|
||||||
import org.elasticsearch.rest.action.search.RestMultiSearchAction;
|
import org.elasticsearch.rest.action.search.RestMultiSearchAction;
|
||||||
|
import org.elasticsearch.rest.action.search.RestSearchAction;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
@ -38,7 +39,7 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
|
|
||||||
public class RestMultiSearchTemplateAction extends BaseRestHandler {
|
public class RestMultiSearchTemplateAction extends BaseRestHandler {
|
||||||
|
|
||||||
private static final Set<String> RESPONSE_PARAMS = Collections.singleton("typed_keys");
|
private static final Set<String> RESPONSE_PARAMS = Collections.singleton(RestSearchAction.TYPED_KEYS_PARAM);
|
||||||
|
|
||||||
private final boolean allowExplicitIndex;
|
private final boolean allowExplicitIndex;
|
||||||
|
|
||||||
|
|
|
@ -45,7 +45,7 @@ import static org.elasticsearch.rest.RestRequest.Method.POST;
|
||||||
|
|
||||||
public class RestSearchTemplateAction extends BaseRestHandler {
|
public class RestSearchTemplateAction extends BaseRestHandler {
|
||||||
|
|
||||||
private static final Set<String> RESPONSE_PARAMS = Collections.singleton("typed_keys");
|
private static final Set<String> RESPONSE_PARAMS = Collections.singleton(RestSearchAction.TYPED_KEYS_PARAM);
|
||||||
|
|
||||||
private static final ObjectParser<SearchTemplateRequest, Void> PARSER;
|
private static final ObjectParser<SearchTemplateRequest, Void> PARSER;
|
||||||
static {
|
static {
|
||||||
|
|
|
@ -48,6 +48,11 @@ setup:
|
||||||
test_missing:
|
test_missing:
|
||||||
missing:
|
missing:
|
||||||
field: "{{missing_field}}"
|
field: "{{missing_field}}"
|
||||||
|
suggest:
|
||||||
|
term_suggest:
|
||||||
|
text: "{{suggest_text}}"
|
||||||
|
term:
|
||||||
|
field: "{{suggest_field}}"
|
||||||
|
|
||||||
- match: { acknowledged: true }
|
- match: { acknowledged: true }
|
||||||
|
|
||||||
|
@ -60,9 +65,12 @@ setup:
|
||||||
params:
|
params:
|
||||||
bool_value: true
|
bool_value: true
|
||||||
missing_field: name
|
missing_field: name
|
||||||
|
suggest_field: name
|
||||||
|
suggest_text: Hamilt
|
||||||
|
|
||||||
- match: { hits.total: 3 }
|
- match: { hits.total: 3 }
|
||||||
- match: { aggregations.missing#test_missing.doc_count: 1 }
|
- match: { aggregations.missing#test_missing.doc_count: 1 }
|
||||||
|
- is_true: suggest.term#term_suggest
|
||||||
|
|
||||||
---
|
---
|
||||||
"Multisearch template with typed_keys parameter":
|
"Multisearch template with typed_keys parameter":
|
||||||
|
@ -81,6 +89,11 @@ setup:
|
||||||
histogram:
|
histogram:
|
||||||
field: "{{histo.field}}"
|
field: "{{histo.field}}"
|
||||||
interval: "{{histo.interval}}"
|
interval: "{{histo.interval}}"
|
||||||
|
suggest:
|
||||||
|
phrase_suggester:
|
||||||
|
text: "{{keywords}}"
|
||||||
|
phrase:
|
||||||
|
field: name
|
||||||
|
|
||||||
- match: { acknowledged: true }
|
- match: { acknowledged: true }
|
||||||
|
|
||||||
|
@ -112,8 +125,11 @@ setup:
|
||||||
histo:
|
histo:
|
||||||
field: float
|
field: float
|
||||||
interval: 5
|
interval: 5
|
||||||
|
keywords: Ruht
|
||||||
|
|
||||||
- match: { responses.0.hits.total: 1 }
|
- match: { responses.0.hits.total: 1 }
|
||||||
- match: { responses.0.aggregations.global#test_global.doc_count: 5 }
|
- match: { responses.0.aggregations.global#test_global.doc_count: 5 }
|
||||||
- match: { responses.0.aggregations.global#test_global.ip_range#test_ip_range.buckets.0.doc_count: 5 }
|
- match: { responses.0.aggregations.global#test_global.ip_range#test_ip_range.buckets.0.doc_count: 5 }
|
||||||
- match: { responses.1.hits.total: 2 }
|
- match: { responses.1.hits.total: 2 }
|
||||||
- match: { responses.1.aggregations.histogram#test_histogram.buckets.0.doc_count: 1 }
|
- match: { responses.1.aggregations.histogram#test_histogram.buckets.0.doc_count: 1 }
|
||||||
|
- is_true: responses.1.suggest.phrase#phrase_suggester
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
},
|
},
|
||||||
"typed_keys": {
|
"typed_keys": {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"description" : "Specify whether aggregation names should be prefixed by their respective types in the response"
|
"description" : "Specify whether aggregation and suggester names should be prefixed by their respective types in the response"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
},
|
},
|
||||||
"typed_keys": {
|
"typed_keys": {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"description" : "Specify whether aggregation names should be prefixed by their respective types in the response"
|
"description" : "Specify whether aggregation and suggester names should be prefixed by their respective types in the response"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -149,7 +149,7 @@
|
||||||
},
|
},
|
||||||
"typed_keys": {
|
"typed_keys": {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"description" : "Specify whether aggregation names should be prefixed by their respective types in the response"
|
"description" : "Specify whether aggregation and suggester names should be prefixed by their respective types in the response"
|
||||||
},
|
},
|
||||||
"version": {
|
"version": {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
},
|
},
|
||||||
"typed_keys": {
|
"typed_keys": {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"description" : "Specify whether aggregation names should be prefixed by their respective types in the response"
|
"description" : "Specify whether aggregation and suggester names should be prefixed by their respective types in the response"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -21,19 +21,20 @@ setup:
|
||||||
type: float
|
type: float
|
||||||
name:
|
name:
|
||||||
type: keyword
|
type: keyword
|
||||||
|
title:
|
||||||
|
type: completion
|
||||||
- do:
|
- do:
|
||||||
bulk:
|
bulk:
|
||||||
refresh: true
|
refresh: true
|
||||||
body:
|
body:
|
||||||
- '{"index": {"_index": "test-0", "_type": "user"}}'
|
- '{"index": {"_index": "test-0", "_type": "user"}}'
|
||||||
- '{"row": 1, "index_start_at": 56, "integer": 38, "float": 12.5713, "name": "Ruth", "bool": true}'
|
- '{"row": 1, "index_start_at": 56, "integer": 38, "float": 12.5713, "name": "Ruth", "bool": true, "title": "doctor"}'
|
||||||
- '{"index": {"_index": "test-0", "_type": "user"}}'
|
- '{"index": {"_index": "test-0", "_type": "user"}}'
|
||||||
- '{"row": 2, "index_start_at": 57, "integer": 42, "float": 15.3393, "name": "Jackie", "surname": "Bowling", "bool": false}'
|
- '{"row": 2, "index_start_at": 57, "integer": 42, "float": 15.3393, "name": "Jackie", "surname": "Bowling", "bool": false}'
|
||||||
- '{"index": {"_index": "test-1", "_type": "user"}}'
|
- '{"index": {"_index": "test-1", "_type": "user"}}'
|
||||||
- '{"row": 3, "index_start_at": 58, "integer": 29, "float": 19.0517, "name": "Stephanie", "bool": true}'
|
- '{"row": 3, "index_start_at": 58, "integer": 29, "float": 19.0517, "name": "Stephanie", "bool": true}'
|
||||||
- '{"index": {"_index": "test-1", "_type": "user"}}'
|
- '{"index": {"_index": "test-1", "_type": "user"}}'
|
||||||
- '{"row": 4, "index_start_at": 59, "integer": 19, "float": 19.3717, "surname": "Hamilton", "bool": true}'
|
- '{"row": 4, "index_start_at": 59, "integer": 19, "float": 19.3717, "surname": "Hamilton", "bool": true, "title": "commandant"}'
|
||||||
- '{"index": {"_index": "test-2", "_type": "user"}}'
|
- '{"index": {"_index": "test-2", "_type": "user"}}'
|
||||||
- '{"row": 5, "index_start_at": 60, "integer": 0, "float": 17.3349, "name": "Natalie", "bool": false}'
|
- '{"row": 5, "index_start_at": 60, "integer": 0, "float": 17.3349, "name": "Natalie", "bool": false}'
|
||||||
|
|
||||||
|
@ -43,12 +44,20 @@ setup:
|
||||||
msearch:
|
msearch:
|
||||||
typed_keys: true
|
typed_keys: true
|
||||||
body:
|
body:
|
||||||
|
# Testing aggegrations
|
||||||
- index: test-*
|
- index: test-*
|
||||||
- {query: {match: {bool: true} }, size: 0, aggs: {test_filter: {filter: {range:{integer: {gte: 20} } } } } }
|
- {query: {match: {bool: true} }, size: 0, aggs: {test_filter: {filter: {range:{integer: {gte: 20} } } } } }
|
||||||
- index: test-1
|
- index: test-1
|
||||||
- {query: {match_all: {} }, size: 0, aggs: {test_range: {range: {field: float, ranges: [ {to: 19.2499999}, {from: 19.25} ] } } } }
|
- {query: {match_all: {} }, size: 0, aggs: {test_range: {range: {field: float, ranges: [ {to: 19.2499999}, {from: 19.25} ] } } } }
|
||||||
- index: test-*
|
- index: test-*
|
||||||
- {query: {bool: {filter: {range: {row: {lt: 5}}} } }, size: 0, aggs: {test_percentiles: {percentiles: {field: float} } } }
|
- {query: {bool: {filter: {range: {row: {lt: 5}}} } }, size: 0, aggs: {test_percentiles: {percentiles: {field: float} } } }
|
||||||
|
# Testing suggesters
|
||||||
|
- index: test-*
|
||||||
|
- {query: {match_all: {} }, size: 0, suggest: {term_suggester: {text: Natalie, term: {field: name } } } }
|
||||||
|
- index: test-*
|
||||||
|
- {query: {match_all: {} }, size: 0, suggest: {completion_suggester: {prefix: doc, completion: {field: title } } } }
|
||||||
|
- index: test-*
|
||||||
|
- {query: {match_all: {} }, size: 0, suggest: {phrase_suggester: {text: Ruht, phrase: {field: name } } } }
|
||||||
|
|
||||||
- match: { responses.0.hits.total: 3 }
|
- match: { responses.0.hits.total: 3 }
|
||||||
- match: { responses.0.aggregations.filter#test_filter.doc_count : 2 }
|
- match: { responses.0.aggregations.filter#test_filter.doc_count : 2 }
|
||||||
|
@ -59,6 +68,9 @@ setup:
|
||||||
- match: { responses.1.aggregations.range#test_range.buckets.1.doc_count : 1 }
|
- match: { responses.1.aggregations.range#test_range.buckets.1.doc_count : 1 }
|
||||||
- match: { responses.2.hits.total: 4 }
|
- match: { responses.2.hits.total: 4 }
|
||||||
- is_true: responses.2.aggregations.tdigest_percentiles#test_percentiles.values
|
- is_true: responses.2.aggregations.tdigest_percentiles#test_percentiles.values
|
||||||
|
- is_true: responses.3.suggest.term#term_suggester
|
||||||
|
- is_true: responses.4.suggest.completion#completion_suggester
|
||||||
|
- is_true: responses.5.suggest.phrase#phrase_suggester
|
||||||
|
|
||||||
---
|
---
|
||||||
"Multisearch test with typed_keys parameter for sampler and significant terms":
|
"Multisearch test with typed_keys parameter for sampler and significant terms":
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
setup:
|
||||||
|
- skip:
|
||||||
|
version: " - 5.3.99"
|
||||||
|
reason: typed_keys parameter was added in 5.4.0
|
||||||
|
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: test
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
number_of_replicas: 0
|
||||||
|
mappings:
|
||||||
|
test:
|
||||||
|
properties:
|
||||||
|
title:
|
||||||
|
type: keyword
|
||||||
|
suggestions:
|
||||||
|
type: completion
|
||||||
|
contexts:
|
||||||
|
-
|
||||||
|
"name" : "format"
|
||||||
|
"type" : "category"
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
refresh: true
|
||||||
|
index: test
|
||||||
|
type: test
|
||||||
|
body:
|
||||||
|
- '{"index": {}}'
|
||||||
|
- '{"title": "Elasticsearch in Action", "suggestions": {"input": "ELK in Action", "contexts": {"format": "ebook"}}}'
|
||||||
|
- '{"index": {}}'
|
||||||
|
- '{"title": "Elasticsearch - The Definitive Guide", "suggestions": {"input": ["Elasticsearch in Action"]}}'
|
||||||
|
|
||||||
|
---
|
||||||
|
"Test typed keys parameter for suggesters":
|
||||||
|
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
typed_keys: true
|
||||||
|
body:
|
||||||
|
query:
|
||||||
|
match_all: {}
|
||||||
|
suggest:
|
||||||
|
text: "Elastic"
|
||||||
|
term_suggester:
|
||||||
|
term:
|
||||||
|
field: title
|
||||||
|
completion_suggester:
|
||||||
|
prefix: "Elastic"
|
||||||
|
completion:
|
||||||
|
field: suggestions
|
||||||
|
context_suggester:
|
||||||
|
prefix: "Elastic"
|
||||||
|
completion:
|
||||||
|
field: suggestions
|
||||||
|
contexts:
|
||||||
|
format: "ebook"
|
||||||
|
phrase_suggester:
|
||||||
|
phrase:
|
||||||
|
field: title
|
||||||
|
|
||||||
|
- is_true: suggest.term#term_suggester
|
||||||
|
- is_true: suggest.completion#completion_suggester
|
||||||
|
- is_true: suggest.completion#context_suggester
|
||||||
|
- is_true: suggest.phrase#phrase_suggester
|
Loading…
Reference in New Issue