1
0
Эх сурвалжийг харах

[Docs] Adding highlighting section to high level client docs (#25751)

Adding a section about how to use highlighting in the SearchSourceBuilder and
how to retrieve highlighted fragments from the SearchResponse.
Christoph Büscher 8 жил өмнө
parent
commit
56b1250a34

+ 67 - 0
client/rest-high-level/src/test/java/org/elasticsearch/client/documentation/SearchDocumentationIT.java

@@ -33,6 +33,7 @@ import org.elasticsearch.action.support.IndicesOptions;
 import org.elasticsearch.action.support.WriteRequest;
 import org.elasticsearch.client.ESRestHighLevelClientTestCase;
 import org.elasticsearch.client.RestHighLevelClient;
+import org.elasticsearch.common.text.Text;
 import org.elasticsearch.common.unit.TimeValue;
 import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.index.query.QueryBuilders;
@@ -49,6 +50,8 @@ import org.elasticsearch.search.aggregations.bucket.terms.Terms.Bucket;
 import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
 import org.elasticsearch.search.aggregations.metrics.avg.Avg;
 import org.elasticsearch.search.builder.SearchSourceBuilder;
+import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
+import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
 import org.elasticsearch.search.sort.ScoreSortBuilder;
 import org.elasticsearch.search.sort.SortOrder;
 import org.elasticsearch.search.suggest.Suggest;
@@ -65,6 +68,7 @@ import java.util.Map;
 import java.util.concurrent.TimeUnit;
 
 import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
+import static org.hamcrest.Matchers.containsString;
 import static org.hamcrest.Matchers.greaterThan;
 
 /**
@@ -330,6 +334,69 @@ public class SearchDocumentationIT extends ESRestHighLevelClientTestCase {
         }
     }
 
+    public void testSearchRequestHighlighting() throws IOException {
+        RestHighLevelClient client = highLevelClient();
+        {
+            BulkRequest request = new BulkRequest();
+            request.add(new IndexRequest("posts", "doc", "1")
+                    .source(XContentType.JSON, "title", "In which order are my Elasticsearch queries executed?", "user",
+                            Arrays.asList("kimchy", "luca"), "innerObject", Collections.singletonMap("key", "value")));
+            request.add(new IndexRequest("posts", "doc", "2")
+                    .source(XContentType.JSON, "title", "Current status and upcoming changes in Elasticsearch", "user",
+                            Arrays.asList("kimchy", "christoph"), "innerObject", Collections.singletonMap("key", "value")));
+            request.add(new IndexRequest("posts", "doc", "3")
+                    .source(XContentType.JSON, "title", "The Future of Federated Search in Elasticsearch", "user",
+                            Arrays.asList("kimchy", "tanguy"), "innerObject", Collections.singletonMap("key", "value")));
+            request.setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE);
+            BulkResponse bulkResponse = client.bulk(request);
+            assertSame(bulkResponse.status(), RestStatus.OK);
+            assertFalse(bulkResponse.hasFailures());
+        }
+        {
+            SearchRequest searchRequest = new SearchRequest();
+            // tag::search-request-highlighting
+            SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
+            HighlightBuilder highlightBuilder = new HighlightBuilder(); // <1>
+            HighlightBuilder.Field highlightTitle =
+                    new HighlightBuilder.Field("title"); // <2>
+            highlightTitle.highlighterType("unified");  // <3>
+            highlightBuilder.field(highlightTitle);  // <4>
+            HighlightBuilder.Field highlightUser = new HighlightBuilder.Field("user");
+            highlightBuilder.field(highlightUser);
+            searchSourceBuilder.highlighter(highlightBuilder);
+            // end::search-request-highlighting
+            searchSourceBuilder.query(QueryBuilders.boolQuery()
+                    .should(matchQuery("title", "Elasticsearch"))
+                    .should(matchQuery("user", "kimchy")));
+            searchRequest.source(searchSourceBuilder);
+            SearchResponse searchResponse = client.search(searchRequest);
+            {
+                // tag::search-request-highlighting-get
+                SearchHits hits = searchResponse.getHits();
+                for (SearchHit hit : hits.getHits()) {
+                    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
+                    HighlightField highlight = highlightFields.get("title"); // <1>
+                    Text[] fragments = highlight.fragments();  // <2>
+                    String fragmentString = fragments[0].string();
+                }
+                // end::search-request-highlighting-get
+                hits = searchResponse.getHits();
+                for (SearchHit hit : hits.getHits()) {
+                    Map<String, HighlightField> highlightFields = hit.getHighlightFields();
+                    HighlightField highlight = highlightFields.get("title");
+                    Text[] fragments = highlight.fragments();
+                    assertEquals(1, fragments.length);
+                    assertThat(fragments[0].string(), containsString("<em>Elasticsearch</em>"));
+                    highlight = highlightFields.get("user");
+                    fragments = highlight.fragments();
+                    assertEquals(1, fragments.length);
+                    assertThat(fragments[0].string(), containsString("<em>kimchy</em>"));
+                }
+            }
+
+        }
+    }
+
     public void testScroll() throws IOException {
         RestHighLevelClient client = highLevelClient();
         {

+ 38 - 1
docs/java-rest/high-level/apis/search.asciidoc

@@ -82,6 +82,28 @@ After this, the `SearchSourceBuilder` only needs to be added to the
 include-tagged::{doc-tests}/SearchDocumentationIT.java[search-source-setter]
 --------------------------------------------------
 
+[[java-rest-high-request-highlighting]]
+===== Requesting Highlighting
+
+Highlighting search results can be achieved by setting a `HighlightBuilder` on the
+`SearchSourceBuilder`. Different highlighting behaviour can be defined for each
+fields by adding one or more `HighlightBuilder.Field` instances to a `HighlightBuilder`.
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-highlighting]
+--------------------------------------------------
+<1> Creates a new `HighlightBuilder`
+<2> Create a field highlighter for the `title` field
+<3> Set the field highlighter type
+<4> Add the field highlighter to the highlight builder
+
+There are many options which are explained in detail in the Rest API documentation. The Rest
+API parameters (e.g. `pre_tags`) are usually changed by
+setters with a similar name (e.g. `#preTags(String ...)`).
+
+Highlighted text fragments can <<java-rest-high-retrieve-highlighting,later be retrieved>> from the `SearchResponse`.
+
 ===== Requesting Aggregations
 
 Aggregations can be added to the search by first creating the appropriate
@@ -110,7 +132,7 @@ include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-suggestion
 the text `kmichy`
 <2> Adds the suggestion builder and names it `suggest_user`
 
-We will later see how to <<java-rest-high-retrieve-suggestions,retrieve suggestions>> from the 
+We will later see how to <<java-rest-high-retrieve-suggestions,retrieve suggestions>> from the
 `SearchResponse`.
 
 [[java-rest-high-document-search-sync]]
@@ -210,6 +232,21 @@ cases need to be cast accordingly:
 include-tagged::{doc-tests}/SearchDocumentationIT.java[search-hits-singleHit-source]
 --------------------------------------------------
 
+[[java-rest-high-retrieve-highlighting]]
+===== Retrieving Highlighting
+
+If <<java-rest-high-request-highlighting,requested>>, highlighted text fragments can be retrieved from each `SearchHit` in the result. The hit object offers
+access to a map of field names to `HighlightField` instances, each of which contains one
+or many highlighted text fragments:
+
+
+["source","java",subs="attributes,callouts,macros"]
+--------------------------------------------------
+include-tagged::{doc-tests}/SearchDocumentationIT.java[search-request-highlighting-get]
+--------------------------------------------------
+<1> Get the highlighting for the `title` field
+<2> Get one or many fragments containing the highlighted field content
+
 [[java-rest-high-retrieve-aggs]]
 ===== Retrieving Aggregations