Add second level of field collapsing (#31808)
* Put second level collapse under inner_hits Closes #24855
This commit is contained in:
parent
f9791cf158
commit
80492cacfc
|
@ -116,3 +116,105 @@ The default is based on the number of data nodes and the default search thread p
|
||||||
|
|
||||||
WARNING: `collapse` cannot be used in conjunction with <<search-request-scroll, scroll>>,
|
WARNING: `collapse` cannot be used in conjunction with <<search-request-scroll, scroll>>,
|
||||||
<<search-request-rescore, rescore>> or <<search-request-search-after, search after>>.
|
<<search-request-rescore, rescore>> or <<search-request-search-after, search after>>.
|
||||||
|
|
||||||
|
==== Second level of collapsing
|
||||||
|
|
||||||
|
Second level of collapsing is also supported and is applied to `inner_hits`.
|
||||||
|
For example, the following request finds the top scored tweets for
|
||||||
|
each country, and within each country finds the top scored tweets
|
||||||
|
for each user.
|
||||||
|
|
||||||
|
[source,js]
|
||||||
|
--------------------------------------------------
|
||||||
|
GET /twitter/_search
|
||||||
|
{
|
||||||
|
"query": {
|
||||||
|
"match": {
|
||||||
|
"message": "elasticsearch"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"collapse" : {
|
||||||
|
"field" : "country",
|
||||||
|
"inner_hits" : {
|
||||||
|
"name": "by_location",
|
||||||
|
"collapse" : {"field" : "user"},
|
||||||
|
"size": 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
--------------------------------------------------
|
||||||
|
// NOTCONSOLE
|
||||||
|
|
||||||
|
|
||||||
|
Response:
|
||||||
|
[source,js]
|
||||||
|
--------------------------------------------------
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"hits": [
|
||||||
|
{
|
||||||
|
"_index": "twitter",
|
||||||
|
"_type": "_doc",
|
||||||
|
"_id": "9",
|
||||||
|
"_score": ...,
|
||||||
|
"_source": {...},
|
||||||
|
"fields": {"country": ["UK"]},
|
||||||
|
"inner_hits":{
|
||||||
|
"by_location": {
|
||||||
|
"hits": {
|
||||||
|
...,
|
||||||
|
"hits": [
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"fields": {"user" : ["user124"]}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"fields": {"user" : ["user589"]}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"fields": {"user" : ["user001"]}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"_index": "twitter",
|
||||||
|
"_type": "_doc",
|
||||||
|
"_id": "1",
|
||||||
|
"_score": ..,
|
||||||
|
"_source": {...},
|
||||||
|
"fields": {"country": ["Canada"]},
|
||||||
|
"inner_hits":{
|
||||||
|
"by_location": {
|
||||||
|
"hits": {
|
||||||
|
...,
|
||||||
|
"hits": [
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"fields": {"user" : ["user444"]}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"fields": {"user" : ["user1111"]}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
...
|
||||||
|
"fields": {"user" : ["user999"]}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
},
|
||||||
|
....
|
||||||
|
]
|
||||||
|
}
|
||||||
|
--------------------------------------------------
|
||||||
|
// NOTCONSOLE
|
||||||
|
|
||||||
|
NOTE: Second level of of collapsing doesn't allow `inner_hits`.
|
|
@ -0,0 +1,141 @@
|
||||||
|
---
|
||||||
|
"two levels fields collapsing":
|
||||||
|
- skip:
|
||||||
|
version: " - 6.99.99"
|
||||||
|
reason: using multiple field collapsing from 7.0 on
|
||||||
|
- do:
|
||||||
|
indices.create:
|
||||||
|
index: addresses
|
||||||
|
body:
|
||||||
|
settings:
|
||||||
|
number_of_shards: 1
|
||||||
|
number_of_replicas: 1
|
||||||
|
mappings:
|
||||||
|
_doc:
|
||||||
|
properties:
|
||||||
|
country: {"type": "keyword"}
|
||||||
|
city: {"type": "keyword"}
|
||||||
|
address: {"type": "text"}
|
||||||
|
|
||||||
|
- do:
|
||||||
|
bulk:
|
||||||
|
refresh: true
|
||||||
|
body:
|
||||||
|
- '{ "index" : { "_index" : "addresses", "_type" : "_doc", "_id" : "1" } }'
|
||||||
|
- '{"country" : "Canada", "city" : "Saskatoon", "address" : "701 Victoria Avenue" }'
|
||||||
|
- '{ "index" : { "_index" : "addresses", "_type" : "_doc", "_id" : "2" } }'
|
||||||
|
- '{"country" : "Canada", "city" : "Toronto", "address" : "74 Victoria Street, Suite, 74 Victoria Street, Suite 300" }'
|
||||||
|
- '{ "index" : { "_index" : "addresses", "_type" : "_doc", "_id" : "3" } }'
|
||||||
|
- '{"country" : "Canada", "city" : "Toronto", "address" : "350 Victoria St" }'
|
||||||
|
- '{ "index" : { "_index" : "addresses", "_type" : "_doc", "_id" : "4" } }'
|
||||||
|
- '{"country" : "Canada", "city" : "Toronto", "address" : "20 Victoria Street" }'
|
||||||
|
- '{ "index" : { "_index" : "addresses", "_type" : "_doc", "_id" : "5" } }'
|
||||||
|
- '{"country" : "UK", "city" : "London", "address" : "58 Victoria Street" }'
|
||||||
|
- '{ "index" : { "_index" : "addresses", "_type" : "_doc", "_id" : "6" } }'
|
||||||
|
- '{"country" : "UK", "city" : "London", "address" : "Victoria Street Victoria Palace Theatre" }'
|
||||||
|
- '{ "index" : { "_index" : "addresses", "_type" : "_doc", "_id" : "7" } }'
|
||||||
|
- '{"country" : "UK", "city" : "Manchester", "address" : "75 Victoria street Westminster" }'
|
||||||
|
- '{ "index" : { "_index" : "addresses", "_type" : "_doc", "_id" : "8" } }'
|
||||||
|
- '{"country" : "UK", "city" : "London", "address" : "Victoria Station Victoria Arcade" }'
|
||||||
|
|
||||||
|
|
||||||
|
# ************* error if internal collapse contains inner_hits
|
||||||
|
- do:
|
||||||
|
catch: /parse_exception/
|
||||||
|
search:
|
||||||
|
index: addresses
|
||||||
|
body:
|
||||||
|
query: { "match" : { "address" : "victoria" }}
|
||||||
|
collapse:
|
||||||
|
field: country
|
||||||
|
inner_hits:
|
||||||
|
collapse:
|
||||||
|
field : city
|
||||||
|
inner_hits: {}
|
||||||
|
|
||||||
|
|
||||||
|
# ************* error if internal collapse contains another collapse
|
||||||
|
- do:
|
||||||
|
catch: /parse_exception/
|
||||||
|
search:
|
||||||
|
index: addresses
|
||||||
|
body:
|
||||||
|
query: { "match" : { "address" : "victoria" }}
|
||||||
|
collapse:
|
||||||
|
field: country
|
||||||
|
inner_hits:
|
||||||
|
collapse:
|
||||||
|
field : city
|
||||||
|
collapse: { field: city }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ************* top scored
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: addresses
|
||||||
|
body:
|
||||||
|
query: { "match" : { "address" : "victoria" }}
|
||||||
|
collapse:
|
||||||
|
field: country
|
||||||
|
inner_hits:
|
||||||
|
name: by_location
|
||||||
|
size: 3
|
||||||
|
collapse:
|
||||||
|
field : city
|
||||||
|
|
||||||
|
- match: { hits.total: 8 }
|
||||||
|
- length: { hits.hits: 2 }
|
||||||
|
- match: { hits.hits.0.fields.country: ["UK"] }
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.total: 4 }
|
||||||
|
# 2 inner hits returned instead of requested 3 as they are collapsed by city
|
||||||
|
- length: { hits.hits.0.inner_hits.by_location.hits.hits : 2}
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.hits.0._id: "8" }
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.hits.0.fields.city: ["London"] }
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.hits.1._id: "7" }
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.hits.1.fields.city: ["Manchester"] }
|
||||||
|
|
||||||
|
- match: { hits.hits.1.fields.country: ["Canada"] }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.total: 4 }
|
||||||
|
# 2 inner hits returned instead of requested 3 as they are collapsed by city
|
||||||
|
- length: { hits.hits.1.inner_hits.by_location.hits.hits : 2 }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.hits.0._id: "1" }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.hits.0.fields.city: ["Saskatoon"] }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.hits.1._id: "3" }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.hits.1.fields.city: ["Toronto"] }
|
||||||
|
|
||||||
|
|
||||||
|
# ************* sorted
|
||||||
|
- do:
|
||||||
|
search:
|
||||||
|
index: addresses
|
||||||
|
body:
|
||||||
|
query: { "match" : { "address" : "victoria" }}
|
||||||
|
collapse:
|
||||||
|
field: country
|
||||||
|
inner_hits:
|
||||||
|
name: by_location
|
||||||
|
size: 3
|
||||||
|
sort: [{ "city": "desc" }]
|
||||||
|
collapse:
|
||||||
|
field : city
|
||||||
|
|
||||||
|
- match: { hits.total: 8 }
|
||||||
|
- length: { hits.hits: 2 }
|
||||||
|
- match: { hits.hits.0.fields.country: ["UK"] }
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.total: 4 }
|
||||||
|
# 2 inner hits returned instead of requested 3 as they are collapsed by city
|
||||||
|
- length: { hits.hits.0.inner_hits.by_location.hits.hits : 2}
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.hits.0._id: "7" }
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.hits.0.fields.city: ["Manchester"] }
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.hits.1._id: "5" }
|
||||||
|
- match: { hits.hits.0.inner_hits.by_location.hits.hits.1.fields.city: ["London"] }
|
||||||
|
|
||||||
|
- match: { hits.hits.1.fields.country: ["Canada"] }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.total: 4 }
|
||||||
|
# 2 inner hits returned instead of requested 3 as they are collapsed by city
|
||||||
|
- length: { hits.hits.1.inner_hits.by_location.hits.hits : 2 }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.hits.0._id: "2" }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.hits.0.fields.city: ["Toronto"] }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.hits.1._id: "1" }
|
||||||
|
- match: { hits.hits.1.inner_hits.by_location.hits.hits.1.fields.city: ["Saskatoon"] }
|
|
@ -87,7 +87,8 @@ final class ExpandSearchPhase extends SearchPhase {
|
||||||
groupQuery.must(origQuery);
|
groupQuery.must(origQuery);
|
||||||
}
|
}
|
||||||
for (InnerHitBuilder innerHitBuilder : innerHitBuilders) {
|
for (InnerHitBuilder innerHitBuilder : innerHitBuilders) {
|
||||||
SearchSourceBuilder sourceBuilder = buildExpandSearchSourceBuilder(innerHitBuilder)
|
CollapseBuilder innerCollapseBuilder = innerHitBuilder.getInnerCollapseBuilder();
|
||||||
|
SearchSourceBuilder sourceBuilder = buildExpandSearchSourceBuilder(innerHitBuilder, innerCollapseBuilder)
|
||||||
.query(groupQuery)
|
.query(groupQuery)
|
||||||
.postFilter(searchRequest.source().postFilter());
|
.postFilter(searchRequest.source().postFilter());
|
||||||
SearchRequest groupRequest = buildExpandSearchRequest(searchRequest, sourceBuilder);
|
SearchRequest groupRequest = buildExpandSearchRequest(searchRequest, sourceBuilder);
|
||||||
|
@ -135,7 +136,7 @@ final class ExpandSearchPhase extends SearchPhase {
|
||||||
return groupRequest;
|
return groupRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
private SearchSourceBuilder buildExpandSearchSourceBuilder(InnerHitBuilder options) {
|
private SearchSourceBuilder buildExpandSearchSourceBuilder(InnerHitBuilder options, CollapseBuilder innerCollapseBuilder) {
|
||||||
SearchSourceBuilder groupSource = new SearchSourceBuilder();
|
SearchSourceBuilder groupSource = new SearchSourceBuilder();
|
||||||
groupSource.from(options.getFrom());
|
groupSource.from(options.getFrom());
|
||||||
groupSource.size(options.getSize());
|
groupSource.size(options.getSize());
|
||||||
|
@ -167,6 +168,9 @@ final class ExpandSearchPhase extends SearchPhase {
|
||||||
groupSource.explain(options.isExplain());
|
groupSource.explain(options.isExplain());
|
||||||
groupSource.trackScores(options.isTrackScores());
|
groupSource.trackScores(options.isTrackScores());
|
||||||
groupSource.version(options.isVersion());
|
groupSource.version(options.isVersion());
|
||||||
|
if (innerCollapseBuilder != null) {
|
||||||
|
groupSource.collapse(innerCollapseBuilder);
|
||||||
|
}
|
||||||
return groupSource;
|
return groupSource;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,7 @@ import org.elasticsearch.search.fetch.subphase.DocValueFieldsContext.FieldAndFor
|
||||||
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
import org.elasticsearch.search.fetch.subphase.FetchSourceContext;
|
||||||
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
|
||||||
import org.elasticsearch.search.sort.SortBuilder;
|
import org.elasticsearch.search.sort.SortBuilder;
|
||||||
|
import org.elasticsearch.search.collapse.CollapseBuilder;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -55,6 +56,8 @@ public final class InnerHitBuilder implements Writeable, ToXContentObject {
|
||||||
public static final ParseField NAME_FIELD = new ParseField("name");
|
public static final ParseField NAME_FIELD = new ParseField("name");
|
||||||
public static final ParseField IGNORE_UNMAPPED = new ParseField("ignore_unmapped");
|
public static final ParseField IGNORE_UNMAPPED = new ParseField("ignore_unmapped");
|
||||||
public static final QueryBuilder DEFAULT_INNER_HIT_QUERY = new MatchAllQueryBuilder();
|
public static final QueryBuilder DEFAULT_INNER_HIT_QUERY = new MatchAllQueryBuilder();
|
||||||
|
public static final ParseField COLLAPSE_FIELD = new ParseField("collapse");
|
||||||
|
public static final ParseField FIELD_FIELD = new ParseField("field");
|
||||||
|
|
||||||
private static final ObjectParser<InnerHitBuilder, Void> PARSER = new ObjectParser<>("inner_hits", InnerHitBuilder::new);
|
private static final ObjectParser<InnerHitBuilder, Void> PARSER = new ObjectParser<>("inner_hits", InnerHitBuilder::new);
|
||||||
|
|
||||||
|
@ -91,6 +94,28 @@ public final class InnerHitBuilder implements Writeable, ToXContentObject {
|
||||||
}, SearchSourceBuilder._SOURCE_FIELD, ObjectParser.ValueType.OBJECT_ARRAY_BOOLEAN_OR_STRING);
|
}, SearchSourceBuilder._SOURCE_FIELD, ObjectParser.ValueType.OBJECT_ARRAY_BOOLEAN_OR_STRING);
|
||||||
PARSER.declareObject(InnerHitBuilder::setHighlightBuilder, (p, c) -> HighlightBuilder.fromXContent(p),
|
PARSER.declareObject(InnerHitBuilder::setHighlightBuilder, (p, c) -> HighlightBuilder.fromXContent(p),
|
||||||
SearchSourceBuilder.HIGHLIGHT_FIELD);
|
SearchSourceBuilder.HIGHLIGHT_FIELD);
|
||||||
|
PARSER.declareField((parser, builder, context) -> {
|
||||||
|
Boolean isParsedCorrectly = false;
|
||||||
|
String field;
|
||||||
|
if (parser.currentToken() == XContentParser.Token.START_OBJECT) {
|
||||||
|
if (parser.nextToken() == XContentParser.Token.FIELD_NAME) {
|
||||||
|
if (FIELD_FIELD.match(parser.currentName(), parser.getDeprecationHandler())) {
|
||||||
|
if (parser.nextToken() == XContentParser.Token.VALUE_STRING){
|
||||||
|
field = parser.text();
|
||||||
|
if (parser.nextToken() == XContentParser.Token.END_OBJECT){
|
||||||
|
isParsedCorrectly = true;
|
||||||
|
CollapseBuilder cb = new CollapseBuilder(field);
|
||||||
|
builder.setInnerCollapse(cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isParsedCorrectly == false) {
|
||||||
|
throw new ParsingException(parser.getTokenLocation(), "Invalid token in the inner collapse");
|
||||||
|
}
|
||||||
|
|
||||||
|
}, COLLAPSE_FIELD, ObjectParser.ValueType.OBJECT);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String name;
|
private String name;
|
||||||
|
@ -109,6 +134,7 @@ public final class InnerHitBuilder implements Writeable, ToXContentObject {
|
||||||
private Set<ScriptField> scriptFields;
|
private Set<ScriptField> scriptFields;
|
||||||
private HighlightBuilder highlightBuilder;
|
private HighlightBuilder highlightBuilder;
|
||||||
private FetchSourceContext fetchSourceContext;
|
private FetchSourceContext fetchSourceContext;
|
||||||
|
private CollapseBuilder innerCollapseBuilder = null;
|
||||||
|
|
||||||
public InnerHitBuilder() {
|
public InnerHitBuilder() {
|
||||||
this.name = null;
|
this.name = null;
|
||||||
|
@ -173,6 +199,9 @@ public final class InnerHitBuilder implements Writeable, ToXContentObject {
|
||||||
boolean hasChildren = in.readBoolean();
|
boolean hasChildren = in.readBoolean();
|
||||||
assert hasChildren == false;
|
assert hasChildren == false;
|
||||||
}
|
}
|
||||||
|
if (in.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
this.innerCollapseBuilder = in.readOptionalWriteable(CollapseBuilder::new);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -218,6 +247,9 @@ public final class InnerHitBuilder implements Writeable, ToXContentObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
out.writeOptionalWriteable(highlightBuilder);
|
out.writeOptionalWriteable(highlightBuilder);
|
||||||
|
if (out.getVersion().onOrAfter(Version.V_7_0_0_alpha1)) {
|
||||||
|
out.writeOptionalWriteable(innerCollapseBuilder);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -501,6 +533,15 @@ public final class InnerHitBuilder implements Writeable, ToXContentObject {
|
||||||
return query;
|
return query;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public InnerHitBuilder setInnerCollapse(CollapseBuilder innerCollapseBuilder) {
|
||||||
|
this.innerCollapseBuilder = innerCollapseBuilder;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CollapseBuilder getInnerCollapseBuilder() {
|
||||||
|
return innerCollapseBuilder;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
public XContentBuilder toXContent(XContentBuilder builder, Params params) throws IOException {
|
||||||
builder.startObject();
|
builder.startObject();
|
||||||
|
@ -550,6 +591,9 @@ public final class InnerHitBuilder implements Writeable, ToXContentObject {
|
||||||
if (highlightBuilder != null) {
|
if (highlightBuilder != null) {
|
||||||
builder.field(SearchSourceBuilder.HIGHLIGHT_FIELD.getPreferredName(), highlightBuilder, params);
|
builder.field(SearchSourceBuilder.HIGHLIGHT_FIELD.getPreferredName(), highlightBuilder, params);
|
||||||
}
|
}
|
||||||
|
if (innerCollapseBuilder != null) {
|
||||||
|
builder.field(COLLAPSE_FIELD.getPreferredName(), innerCollapseBuilder);
|
||||||
|
}
|
||||||
builder.endObject();
|
builder.endObject();
|
||||||
return builder;
|
return builder;
|
||||||
}
|
}
|
||||||
|
@ -572,13 +616,14 @@ public final class InnerHitBuilder implements Writeable, ToXContentObject {
|
||||||
Objects.equals(scriptFields, that.scriptFields) &&
|
Objects.equals(scriptFields, that.scriptFields) &&
|
||||||
Objects.equals(fetchSourceContext, that.fetchSourceContext) &&
|
Objects.equals(fetchSourceContext, that.fetchSourceContext) &&
|
||||||
Objects.equals(sorts, that.sorts) &&
|
Objects.equals(sorts, that.sorts) &&
|
||||||
Objects.equals(highlightBuilder, that.highlightBuilder);
|
Objects.equals(highlightBuilder, that.highlightBuilder) &&
|
||||||
|
Objects.equals(innerCollapseBuilder, that.innerCollapseBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(name, ignoreUnmapped, from, size, explain, version, trackScores,
|
return Objects.hash(name, ignoreUnmapped, from, size, explain, version, trackScores,
|
||||||
storedFieldsContext, docValueFields, scriptFields, fetchSourceContext, sorts, highlightBuilder);
|
storedFieldsContext, docValueFields, scriptFields, fetchSourceContext, sorts, highlightBuilder, innerCollapseBuilder);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static InnerHitBuilder fromXContent(XContentParser parser) throws IOException {
|
public static InnerHitBuilder fromXContent(XContentParser parser) throws IOException {
|
||||||
|
|
Loading…
Reference in New Issue