use of org.opensearch.index.query.InnerHitBuilder in project OpenSearch by opensearch-project.
the class InnerHitsIT method testInnerHitsWithObjectFieldThatHasANestedField.
public void testInnerHitsWithObjectFieldThatHasANestedField() throws Exception {
assertAcked(prepareCreate("articles").setSettings(Settings.builder().put("index.number_of_shards", 1)).setMapping(jsonBuilder().startObject().startObject("properties").startObject("comments").field("type", "object").startObject("properties").startObject("messages").field("type", "nested").endObject().endObject().endObject().endObject().endObject()));
List<IndexRequestBuilder> requests = new ArrayList<>();
requests.add(client().prepareIndex("articles").setId("1").setSource(jsonBuilder().startObject().field("title", "quick brown fox").startArray("comments").startObject().startArray("messages").startObject().field("message", "fox eat quick").endObject().startObject().field("message", "bear eat quick").endObject().endArray().endObject().startObject().startArray("messages").startObject().field("message", "no fox").endObject().endArray().endObject().endArray().endObject()));
indexRandom(true, requests);
Exception e = expectThrows(Exception.class, () -> client().prepareSearch("articles").setQuery(nestedQuery("comments.messages", matchQuery("comments.messages.message", "fox"), ScoreMode.Avg).innerHit(new InnerHitBuilder())).get());
assertEquals("Cannot execute inner hits. One or more parent object fields of nested field [comments.messages] are " + "not nested. All parent fields need to be nested fields too", e.getCause().getCause().getMessage());
e = expectThrows(Exception.class, () -> client().prepareSearch("articles").setQuery(nestedQuery("comments.messages", matchQuery("comments.messages.message", "fox"), ScoreMode.Avg).innerHit(new InnerHitBuilder().setFetchSourceContext(new FetchSourceContext(true)))).get());
assertEquals("Cannot execute inner hits. One or more parent object fields of nested field [comments.messages] are " + "not nested. All parent fields need to be nested fields too", e.getCause().getCause().getMessage());
SearchResponse response = client().prepareSearch("articles").setQuery(nestedQuery("comments.messages", matchQuery("comments.messages.message", "fox"), ScoreMode.Avg).innerHit(new InnerHitBuilder().setFetchSourceContext(new FetchSourceContext(false)))).get();
assertNoFailures(response);
assertHitCount(response, 1);
SearchHit hit = response.getHits().getAt(0);
assertThat(hit.getId(), equalTo("1"));
SearchHits messages = hit.getInnerHits().get("comments.messages");
assertThat(messages.getTotalHits().value, equalTo(2L));
assertThat(messages.getAt(0).getId(), equalTo("1"));
assertThat(messages.getAt(0).getNestedIdentity().getField().string(), equalTo("comments.messages"));
assertThat(messages.getAt(0).getNestedIdentity().getOffset(), equalTo(2));
assertThat(messages.getAt(0).getNestedIdentity().getChild(), nullValue());
assertThat(messages.getAt(1).getId(), equalTo("1"));
assertThat(messages.getAt(1).getNestedIdentity().getField().string(), equalTo("comments.messages"));
assertThat(messages.getAt(1).getNestedIdentity().getOffset(), equalTo(0));
assertThat(messages.getAt(1).getNestedIdentity().getChild(), nullValue());
response = client().prepareSearch("articles").setQuery(nestedQuery("comments.messages", matchQuery("comments.messages.message", "bear"), ScoreMode.Avg).innerHit(new InnerHitBuilder().setFetchSourceContext(new FetchSourceContext(false)))).get();
assertNoFailures(response);
assertHitCount(response, 1);
hit = response.getHits().getAt(0);
assertThat(hit.getId(), equalTo("1"));
messages = hit.getInnerHits().get("comments.messages");
assertThat(messages.getTotalHits().value, equalTo(1L));
assertThat(messages.getAt(0).getId(), equalTo("1"));
assertThat(messages.getAt(0).getNestedIdentity().getField().string(), equalTo("comments.messages"));
assertThat(messages.getAt(0).getNestedIdentity().getOffset(), equalTo(1));
assertThat(messages.getAt(0).getNestedIdentity().getChild(), nullValue());
// index the message in an object form instead of an array
requests = new ArrayList<>();
requests.add(client().prepareIndex("articles").setId("1").setSource(jsonBuilder().startObject().field("title", "quick brown fox").startObject("comments").startObject("messages").field("message", "fox eat quick").endObject().endObject().endObject()));
indexRandom(true, requests);
response = client().prepareSearch("articles").setQuery(nestedQuery("comments.messages", matchQuery("comments.messages.message", "fox"), ScoreMode.Avg).innerHit(new InnerHitBuilder().setFetchSourceContext(new FetchSourceContext(false)))).get();
assertNoFailures(response);
assertHitCount(response, 1);
hit = response.getHits().getAt(0);
assertThat(hit.getId(), equalTo("1"));
messages = hit.getInnerHits().get("comments.messages");
assertThat(messages.getTotalHits().value, equalTo(1L));
assertThat(messages.getAt(0).getId(), equalTo("1"));
assertThat(messages.getAt(0).getNestedIdentity().getField().string(), equalTo("comments.messages"));
assertThat(messages.getAt(0).getNestedIdentity().getOffset(), equalTo(0));
assertThat(messages.getAt(0).getNestedIdentity().getChild(), nullValue());
}
use of org.opensearch.index.query.InnerHitBuilder in project OpenSearch by opensearch-project.
the class ExpandSearchPhase method run.
@Override
public void run() {
if (isCollapseRequest() && searchResponse.hits().getHits().length > 0) {
SearchRequest searchRequest = context.getRequest();
CollapseBuilder collapseBuilder = searchRequest.source().collapse();
final List<InnerHitBuilder> innerHitBuilders = collapseBuilder.getInnerHits();
MultiSearchRequest multiRequest = new MultiSearchRequest();
if (collapseBuilder.getMaxConcurrentGroupRequests() > 0) {
multiRequest.maxConcurrentSearchRequests(collapseBuilder.getMaxConcurrentGroupRequests());
}
for (SearchHit hit : searchResponse.hits().getHits()) {
BoolQueryBuilder groupQuery = new BoolQueryBuilder();
Object collapseValue = hit.field(collapseBuilder.getField()).getValue();
if (collapseValue != null) {
groupQuery.filter(QueryBuilders.matchQuery(collapseBuilder.getField(), collapseValue));
} else {
groupQuery.mustNot(QueryBuilders.existsQuery(collapseBuilder.getField()));
}
QueryBuilder origQuery = searchRequest.source().query();
if (origQuery != null) {
groupQuery.must(origQuery);
}
for (InnerHitBuilder innerHitBuilder : innerHitBuilders) {
CollapseBuilder innerCollapseBuilder = innerHitBuilder.getInnerCollapseBuilder();
SearchSourceBuilder sourceBuilder = buildExpandSearchSourceBuilder(innerHitBuilder, innerCollapseBuilder).query(groupQuery).postFilter(searchRequest.source().postFilter());
SearchRequest groupRequest = new SearchRequest(searchRequest);
groupRequest.source(sourceBuilder);
multiRequest.add(groupRequest);
}
}
context.getSearchTransport().sendExecuteMultiSearch(multiRequest, context.getTask(), ActionListener.wrap(response -> {
Iterator<MultiSearchResponse.Item> it = response.iterator();
for (SearchHit hit : searchResponse.hits.getHits()) {
for (InnerHitBuilder innerHitBuilder : innerHitBuilders) {
MultiSearchResponse.Item item = it.next();
if (item.isFailure()) {
context.onPhaseFailure(this, "failed to expand hits", item.getFailure());
return;
}
SearchHits innerHits = item.getResponse().getHits();
if (hit.getInnerHits() == null) {
hit.setInnerHits(new HashMap<>(innerHitBuilders.size()));
}
hit.getInnerHits().put(innerHitBuilder.getName(), innerHits);
}
}
context.sendSearchResponse(searchResponse, queryResults);
}, context::onFailure));
} else {
context.sendSearchResponse(searchResponse, queryResults);
}
}
use of org.opensearch.index.query.InnerHitBuilder in project OpenSearch by opensearch-project.
the class HasChildQueryBuilderTests method testExtractInnerHitBuildersWithDuplicate.
public void testExtractInnerHitBuildersWithDuplicate() {
final HasChildQueryBuilder queryBuilder = new HasChildQueryBuilder(CHILD_DOC, new WrapperQueryBuilder(new MatchAllQueryBuilder().toString()), ScoreMode.None);
queryBuilder.innerHit(new InnerHitBuilder("some_name"));
IllegalArgumentException e = expectThrows(IllegalArgumentException.class, () -> InnerHitContextBuilder.extractInnerHits(queryBuilder, Collections.singletonMap("some_name", null)));
assertEquals("[inner_hits] already contains an entry for key [some_name]", e.getMessage());
}
use of org.opensearch.index.query.InnerHitBuilder in project OpenSearch by opensearch-project.
the class ChildQuerySearchIT method testHasChildInnerHitsHighlighting.
public void testHasChildInnerHitsHighlighting() throws Exception {
assertAcked(prepareCreate("test").setMapping(buildParentJoinFieldMappingFromSimplifiedDef("join_field", true, "parent", "child")));
ensureGreen();
createIndexRequest("test", "parent", "1", null, "p_field", 1).get();
createIndexRequest("test", "child", "2", "1", "c_field", "foo bar").get();
refresh();
SearchResponse searchResponse = client().prepareSearch("test").setQuery(hasChildQuery("child", matchQuery("c_field", "foo"), ScoreMode.None).innerHit(new InnerHitBuilder().setHighlightBuilder(new HighlightBuilder().field(new Field("c_field").highlightQuery(QueryBuilders.matchQuery("c_field", "bar")))))).get();
assertNoFailures(searchResponse);
assertThat(searchResponse.getHits().getTotalHits().value, equalTo(1L));
assertThat(searchResponse.getHits().getHits()[0].getId(), equalTo("1"));
SearchHit[] searchHits = searchResponse.getHits().getHits()[0].getInnerHits().get("child").getHits();
assertThat(searchHits.length, equalTo(1));
assertThat(searchHits[0].getHighlightFields().get("c_field").getFragments().length, equalTo(1));
assertThat(searchHits[0].getHighlightFields().get("c_field").getFragments()[0].string(), equalTo("foo <em>bar</em>"));
}
use of org.opensearch.index.query.InnerHitBuilder in project OpenSearch by opensearch-project.
the class InnerHitsIT method testParentChildMultipleLayers.
public void testParentChildMultipleLayers() throws Exception {
assertAcked(prepareCreate("articles").setMapping(addFieldMappings(buildParentJoinFieldMappingFromSimplifiedDef("join_field", true, "article", "comment", "comment", "remark"), "title", "text", "message", "text")));
List<IndexRequestBuilder> requests = new ArrayList<>();
requests.add(createIndexRequest("articles", "article", "1", null, "title", "quick brown fox"));
requests.add(createIndexRequest("articles", "comment", "3", "1", "message", "fox eat quick"));
requests.add(createIndexRequest("articles", "remark", "5", "3", "message", "good").setRouting("1"));
requests.add(createIndexRequest("articles", "article", "2", null, "title", "big gray elephant"));
requests.add(createIndexRequest("articles", "comment", "4", "2", "message", "elephant captured"));
requests.add(createIndexRequest("articles", "remark", "6", "4", "message", "bad").setRouting("2"));
indexRandom(true, requests);
SearchResponse response = client().prepareSearch("articles").setQuery(hasChildQuery("comment", hasChildQuery("remark", matchQuery("message", "good"), ScoreMode.None).innerHit(new InnerHitBuilder()), ScoreMode.None).innerHit(new InnerHitBuilder())).get();
assertNoFailures(response);
assertHitCount(response, 1);
assertSearchHit(response, 1, hasId("1"));
assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
SearchHits innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
assertThat(innerHits.getTotalHits().value, equalTo(1L));
assertThat(innerHits.getAt(0).getId(), equalTo("3"));
innerHits = innerHits.getAt(0).getInnerHits().get("remark");
assertThat(innerHits.getTotalHits().value, equalTo(1L));
assertThat(innerHits.getAt(0).getId(), equalTo("5"));
response = client().prepareSearch("articles").setQuery(hasChildQuery("comment", hasChildQuery("remark", matchQuery("message", "bad"), ScoreMode.None).innerHit(new InnerHitBuilder()), ScoreMode.None).innerHit(new InnerHitBuilder())).get();
assertNoFailures(response);
assertHitCount(response, 1);
assertSearchHit(response, 1, hasId("2"));
assertThat(response.getHits().getAt(0).getInnerHits().size(), equalTo(1));
innerHits = response.getHits().getAt(0).getInnerHits().get("comment");
assertThat(innerHits.getTotalHits().value, equalTo(1L));
assertThat(innerHits.getAt(0).getId(), equalTo("4"));
innerHits = innerHits.getAt(0).getInnerHits().get("remark");
assertThat(innerHits.getTotalHits().value, equalTo(1L));
assertThat(innerHits.getAt(0).getId(), equalTo("6"));
}
Aggregations