1

I want to explicitly order highlighted fields using the Elasticsearch Java API Client 7.16.

In other words I want to build the following request

GET /_search
{
  "highlight": {
    "fields": [
      { "a": {} },
      { "b": {} },
      { "c": {} }
    ]
  }
}

Unfortunately the following code ignores the insertion order:

        new Highlight.Builder()
            .fields("a", new HighlightField.Builder().build())
            .fields("b", new HighlightField.Builder().build())
            .fields("c", new HighlightField.Builder().build());

Actually all available fields() methods eventually put the data in the unordered map. So my request actually is following:

GET /_search
{
  "highlight": {
    "fields": {
      "b": {},
      "c": {},
      "a": {}
    }
  }
}

Is there any other Java API that allows to control the order of highlighted fields?

2 Answers 2

1

As i know this is not possible and this is not issue of elasticsearch but it is how JSON work. Below is mentioned in JSON documentation.

An object is an unordered set of name/value pairs

I am not sure why you want to rely on order. You should not rely on the ordering of elements within a JSON object.

You can pass Map of field like below for order, just check javadoc:

    Map<String, HighlightField> test = new HashMap();
    test.put("a", new HighlightField.Builder().build());
    test.put("b", new HighlightField.Builder().build());
    test.put("b", new HighlightField.Builder().build());
    
    Builder highlight = new Highlight.Builder().fields(test);
Sign up to request clarification or add additional context in comments.

5 Comments

ElasticSearch allows to use a list of objects to get control on the order. GET /_search { "highlight": { "fields": [ { "title": {} }, { "text": {} } ] } } I want to build this query using Java API.
@igor please check my update answer.
In the answer the HashMap used, so it also has no guaranty about the order of the elements. Even if the LinkedHasMap will be passed to fields(orderedMap) then internally ES client will generate the json object with sorted field names. But that still will be the object, not the list.
Did you try with hashmap or not ?
I tried that with the LinkedHashMap. Did you? There is no point to use HashMap and hope for insertion order to be preserved.
0

There is class HighlightBuilder present in package

package org.elasticsearch.search.fetch.subphase.highlight;

Which has following property as member variable,

private boolean useExplicitFieldOrder = false;

The you can build

 List<HighlightBuilder.Field> fields1 = new ArrayList<>();
            fields1.add(new HighlightBuilder.Field("a"));
            fields1.add(new HighlightBuilder.Field("b"));
            fields1.add(new HighlightBuilder.Field("c"));
    
HighlightBuilder highlightBuilder = new HighlightBuilder(null,null,fields1).useExplicitFieldOrder(true);

Another way:

To Generate the explicit ordering Json :

 boolean useExplicitFieldOrder = true;
  XContentBuilder builder = XContentFactory.jsonBuilder();
        builder.prettyPrint();
        builder.startObject();
        builder.startObject("highlight");
        if (fields != null) {
            if (useExplicitFieldOrder) {
                builder.startArray("fields");
            } else {
                builder.startObject("fields");
            }
            for (HighlightField field : fields) {
                if (useExplicitFieldOrder) {
                    builder.startObject();
                }
                builder.startObject(field.field());
                builder.endObject();
                if (useExplicitFieldOrder) {
                    builder.endObject();
                }
            }
            if (useExplicitFieldOrder) {
                builder.endArray();
            } else {
                builder.endObject();
            }
        }
        builder.endObject();
        builder.endObject();
        String json = Strings.toString(builder);
        System.out.println(json);

It will o/p as follow:

{
  "highlight" : {
    "fields" : [
      {
        "a" : { }
      },
      {
        "b" : { }
      },
      {
        "c" : { }
      }
    ]
  }
}

3 Comments

I'm using: implementation("co.elastic.clients:elasticsearch-java:7.16.2")
@igor the above package are present in implementation 'org.elasticsearch:elasticsearch:7.16.2', but though it creates the the Json which explicitly ordering requires(as you have given), there seems to be no way to use the above HighlighterBuilder as new client only exposes Highlight method.
Also beside this, we can generate the required Json format for explicitly ordering(see updated answer), but AFAIK there seems to be no way to send that Json directly as query using new Java client, can you confirm this?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.