Repository: searchbox-io/Jest
Pull request #501 (2017-04-21 00:14:36)

Support unmapped_type in Sort
https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-sort.html#_ignoring_unmapped_fields


Patch:
diff --git a/jest-common/src/main/java/io/searchbox/core/search/sort/Sort.java b/jest-common/src/main/java/io/searchbox/core/search/sort/Sort.java
index 22779407..fe2fef4c 100644
--- a/jest-common/src/main/java/io/searchbox/core/search/sort/Sort.java
+++ b/jest-common/src/main/java/io/searchbox/core/search/sort/Sort.java
@@ -17,6 +17,7 @@ public class Sort {
     private Sorting order;
     private Object missing;
     private Boolean unmapped;
+    private String unmappedType;
 
     public Sort(String field) {
         this.field = field;
@@ -39,6 +40,10 @@ public class Sort {
         this.unmapped = true;
     }
 
+    public void setUnmappedType(String unmappedType) {
+        this.unmappedType = unmappedType;
+    }
+
     public JsonObject toJsonObject() {
         JsonObject sortDefinition = new JsonObject();
         if (order != null) {
@@ -50,6 +55,9 @@ public class Sort {
         if (unmapped != null) {
             sortDefinition.add("ignore_unmapped", new JsonPrimitive(unmapped));
         }
+        if(unmappedType != null) {
+            sortDefinition.add("unmapped_type", new JsonPrimitive(unmappedType));
+        }
 
         JsonObject sortObject = new JsonObject();
         sortObject.add(field, sortDefinition);


Test patch:
diff --git a/jest-common/src/test/java/io/searchbox/core/search/sort/SortTest.java b/jest-common/src/test/java/io/searchbox/core/search/sort/SortTest.java
index 3ec115de..22b9be0f 100644
--- a/jest-common/src/test/java/io/searchbox/core/search/sort/SortTest.java
+++ b/jest-common/src/test/java/io/searchbox/core/search/sort/SortTest.java
@@ -103,4 +103,13 @@ public class SortTest {
         JSONAssert.assertEquals(expectedJson, new Gson().toJson(actualJsonObject), false);
     }
 
+    @Test
+    public void testJsonSerializationWithUnmappedType() throws JSONException {
+        String expectedJson = "{\"my_field\":{\"unmapped_type\":\"long\"}}";
+        Sort s = new Sort("my_field");
+        s.setUnmappedType("long");
+        JsonObject actualJsonObject = s.toJsonObject();
+
+        JSONAssert.assertEquals(expectedJson, new Gson().toJson(actualJsonObject), false);
+    }
 }
diff --git a/jest/src/test/java/io/searchbox/core/search/sort/SortIntegrationTest.java b/jest/src/test/java/io/searchbox/core/search/sort/SortIntegrationTest.java
index 72b2279a..1451c233 100644
--- a/jest/src/test/java/io/searchbox/core/search/sort/SortIntegrationTest.java
+++ b/jest/src/test/java/io/searchbox/core/search/sort/SortIntegrationTest.java
@@ -1,18 +1,19 @@
 package io.searchbox.core.search.sort;
 
+import com.google.gson.*;
 import io.searchbox.client.JestResult;
 import io.searchbox.common.AbstractIntegrationTest;
 import io.searchbox.core.Search;
 import org.elasticsearch.action.admin.indices.mapping.put.PutMappingRequest;
 import org.elasticsearch.action.index.IndexRequest;
 import org.elasticsearch.action.support.WriteRequest;
+import org.elasticsearch.common.xcontent.XContentType;
 import org.elasticsearch.test.ESIntegTestCase;
 import org.junit.Before;
 import org.junit.Test;
 
 import java.io.IOException;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * @author ferhat
@@ -23,6 +24,7 @@ public class SortIntegrationTest extends AbstractIntegrationTest {
 
     String query = "{\"query\":{ \"match_all\" : { }}}";
     String index = "ranker";
+    String anotherIndex = "another_ranker";
     String type = "ranking";
 
     @Before
@@ -30,14 +32,25 @@ public class SortIntegrationTest extends AbstractIntegrationTest {
         createIndex(index);
         client().admin().indices().putMapping(new PutMappingRequest(index)
                         .type(type)
-                        .source("{\"ranking\":{\"properties\":{\"rank\":{\"store\":true,\"type\":\"integer\"}}}}")
+                        .source("{\"ranking\":{\"properties\":{\"rank\":{\"store\":true,\"type\":\"integer\"}}}}", XContentType.JSON)
         ).actionGet();
 
-        client().index(new IndexRequest(index, type).source("{\"rank\":10}").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)).actionGet();
-        client().index(new IndexRequest(index, type).source("{\"rank\":5}").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)).actionGet();
-        client().index(new IndexRequest(index, type).source("{\"rank\":8}").setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)).actionGet();
+        client().index(new IndexRequest(index, type).source("{\"rank\":10}", XContentType.JSON).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)).actionGet();
+        client().index(new IndexRequest(index, type).source("{\"rank\":5}", XContentType.JSON).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)).actionGet();
+        client().index(new IndexRequest(index, type).source("{\"rank\":8}", XContentType.JSON).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)).actionGet();
 
-        ensureSearchable(index);
+        createIndex(anotherIndex);
+        client().admin().indices().putMapping(new PutMappingRequest(anotherIndex)
+                .type(type)
+                .source("{\"ranking\":{\"properties\":{\"rank\":{\"store\":true,\"type\":\"integer\"}, \"rankType\":{\"store\":true,\"type\":\"integer\"}}}}",
+                        XContentType.JSON)
+        ).actionGet();
+
+        client().index(new IndexRequest(anotherIndex, type).source("{\"rank\":90, \"rankType\":0}", XContentType.JSON).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)).actionGet();
+        client().index(new IndexRequest(anotherIndex, type).source("{\"rank\":90, \"rankType\":1}", XContentType.JSON).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)).actionGet();
+        client().index(new IndexRequest(anotherIndex, type).source("{\"rank\":101, \"rankType\":1}", XContentType.JSON).setRefreshPolicy(WriteRequest.RefreshPolicy.IMMEDIATE)).actionGet();
+
+        ensureSearchable(index, anotherIndex);
     }
 
     @Test
@@ -50,11 +63,12 @@ public class SortIntegrationTest extends AbstractIntegrationTest {
                 .build();
         JestResult result = client.execute(search);
         assertTrue(result.getErrorMessage(), result.isSucceeded());
-        List hits = ((List) ((Map) result.getJsonMap().get("hits")).get("hits"));
+        JsonObject object = (JsonObject) result.getJsonObject().get("hits");
+        JsonArray hits = (JsonArray) object.get("hits");
         assertEquals(3, hits.size());
-        assertEquals(5D, ((Map) ((Map) hits.get(0)).get("_source")).get("rank"));
-        assertEquals(8D, ((Map) ((Map) hits.get(1)).get("_source")).get("rank"));
-        assertEquals(10D, ((Map) ((Map) hits.get(2)).get("_source")).get("rank"));
+        assertEquals(5, ((JsonObject) ((JsonObject) hits.get(0)).get("_source")).get("rank").getAsInt());
+        assertEquals(8, ((JsonObject) ((JsonObject) hits.get(1)).get("_source")).get("rank").getAsInt());
+        assertEquals(10, ((JsonObject) ((JsonObject) hits.get(2)).get("_source")).get("rank").getAsInt());
     }
 
     @Test
@@ -67,11 +81,66 @@ public class SortIntegrationTest extends AbstractIntegrationTest {
                 .build();
         JestResult result = client.execute(search);
         assertTrue(result.getErrorMessage(), result.isSucceeded());
-        List hits = ((List) ((Map) result.getJsonMap().get("hits")).get("hits"));
+        JsonObject object = (JsonObject) result.getJsonObject().get("hits");
+        JsonArray hits = (JsonArray) object.get("hits");
+        assertEquals(3, hits.size());
+        assertEquals(5, ((JsonObject) ((JsonObject) hits.get(2)).get("_source")).get("rank").getAsInt());
+        assertEquals(8, ((JsonObject) ((JsonObject) hits.get(1)).get("_source")).get("rank").getAsInt());
+        assertEquals(10, ((JsonObject) ((JsonObject) hits.get(0)).get("_source")).get("rank").getAsInt());
+    }
+
+    @Test
+    public void searchWithMultiIndexSortFieldUnmapped() throws IOException {
+        List<Sort> sorts = new ArrayList<>();
+        sorts.add(new Sort("rank"));
+        Sort sort = new Sort("rankType", Sort.Sorting.DESC);
+        sorts.add(sort);
+
+        Search search = new Search.Builder(query)
+                .addSort(sorts)
+                .addIndex(index)
+                .addIndex(anotherIndex)
+                .addType(type)
+                .build();
+        JestResult result = client.execute(search);
+        assertTrue(result.getErrorMessage(), result.isSucceeded());
+        JsonObject object = (JsonObject) result.getJsonObject().get("hits");
+        JsonArray hits = (JsonArray) object.get("hits");
         assertEquals(3, hits.size());
-        assertEquals(5D, ((Map) ((Map) hits.get(2)).get("_source")).get("rank"));
-        assertEquals(8D, ((Map) ((Map) hits.get(1)).get("_source")).get("rank"));
-        assertEquals(10D, ((Map) ((Map) hits.get(0)).get("_source")).get("rank"));
+        assertNotEquals(index, ((JsonObject) hits.get(0)).get("_index").getAsString());
+        assertNotEquals(index, ((JsonObject) hits.get(1)).get("_index").getAsString());
+        assertNotEquals(index, ((JsonObject) hits.get(2)).get("_index").getAsString());
+
+        sorts.remove(1);
+        sort.setUnmappedType("integer");
+        sorts.add(sort);
+
+        search = new Search.Builder(query)
+                .addSort(sorts)
+                .addIndex(index)
+                .addIndex(anotherIndex)
+                .addType(type)
+                .build();
+        result = client.execute(search);
+        assertTrue(result.getErrorMessage(), result.isSucceeded());
+        object = (JsonObject) result.getJsonObject().get("hits");
+        hits = (JsonArray) object.get("hits");
+        assertEquals(6, hits.size());
+        assertEquals(5, ((JsonObject) ((JsonObject) hits.get(0)).get("_source")).get("rank").getAsInt());
+        assertEquals(index, ((JsonObject) hits.get(0)).get("_index").getAsString());
+        assertEquals(8, ((JsonObject) ((JsonObject) hits.get(1)).get("_source")).get("rank").getAsInt());
+        assertEquals(index, ((JsonObject) hits.get(1)).get("_index").getAsString());
+        assertEquals(10, ((JsonObject) ((JsonObject) hits.get(2)).get("_source")).get("rank").getAsInt());
+        assertEquals(index, ((JsonObject) hits.get(2)).get("_index").getAsString());
+        assertEquals(90, ((JsonObject) ((JsonObject) hits.get(3)).get("_source")).get("rank").getAsInt());
+        assertEquals(1, ((JsonObject) ((JsonObject) hits.get(3)).get("_source")).get("rankType").getAsInt());
+        assertEquals(anotherIndex, ((JsonObject) hits.get(3)).get("_index").getAsString());
+        assertEquals(90, ((JsonObject) ((JsonObject) hits.get(4)).get("_source")).get("rank").getAsInt());
+        assertEquals(0, ((JsonObject) ((JsonObject) hits.get(4)).get("_source")).get("rankType").getAsInt());
+        assertEquals(anotherIndex, ((JsonObject) hits.get(4)).get("_index").getAsString());
+        assertEquals(101, ((JsonObject) ((JsonObject) hits.get(5)).get("_source")).get("rank").getAsInt());
+        assertEquals(1, ((JsonObject) ((JsonObject) hits.get(5)).get("_source")).get("rankType").getAsInt());
+        assertEquals(anotherIndex, ((JsonObject) hits.get(5)).get("_index").getAsString());
     }
 
 }