Repository: searchbox-io/Jest
Pull request #395 (2016-08-20 01:26:08)

Surface "key-as-string" attribute for TermsAggregation
While running a terms aggregation query, the resulting buckets may contain
a "key_as_string" field depending on the fields datatype.  I currently have a need to get at that field to display a propertly formated date field instead of the epoch in millis that is currently returned in the "key" field.  Currently there is no way in the TermsAggregation.Entry class to get at this "key_as_string" field.  This commit simply makes that attribute available and defaults the value to the "key" value if no "key_as_string" field was returned in the result json. 

Address issue:  [394](https://github.com/searchbox-io/Jest/issues/394)


Patch:
diff --git a/jest-common/src/main/java/io/searchbox/core/search/aggregation/TermsAggregation.java b/jest-common/src/main/java/io/searchbox/core/search/aggregation/TermsAggregation.java
index 93472c21..797fc097 100644
--- a/jest-common/src/main/java/io/searchbox/core/search/aggregation/TermsAggregation.java
+++ b/jest-common/src/main/java/io/searchbox/core/search/aggregation/TermsAggregation.java
@@ -14,6 +14,7 @@ import static io.searchbox.core.search.aggregation.AggregationField.DOC_COUNT;
 import static io.searchbox.core.search.aggregation.AggregationField.DOC_COUNT_ERROR_UPPER_BOUND;
 import static io.searchbox.core.search.aggregation.AggregationField.KEY;
 import static io.searchbox.core.search.aggregation.AggregationField.SUM_OTHER_DOC_COUNT;
+import static io.searchbox.core.search.aggregation.AggregationField.KEY_AS_STRING;;
 
 /**
  * @author cfstout
@@ -44,8 +45,11 @@ public class TermsAggregation extends BucketAggregation {
     private void parseBuckets(JsonArray bucketsSource) {
         for(JsonElement bucketElement : bucketsSource) {
             JsonObject bucket = (JsonObject) bucketElement;
-            Entry entry = new Entry(bucket, bucket.get(String.valueOf(KEY)).getAsString(), bucket.get(String.valueOf(DOC_COUNT)).getAsLong());
-            buckets.add(entry);
+            if (bucket.has(String.valueOf(KEY_AS_STRING))) {
+            	buckets.add(new Entry(bucket, bucket.get(String.valueOf(KEY)).getAsString(), bucket.get(String.valueOf(KEY_AS_STRING)).getAsString(), bucket.get(String.valueOf(DOC_COUNT)).getAsLong()));
+            } else {
+            	buckets.add(new Entry(bucket, bucket.get(String.valueOf(KEY)).getAsString(), bucket.get(String.valueOf(DOC_COUNT)).getAsLong()));
+            }
         }
     }
 
@@ -63,16 +67,26 @@ public class TermsAggregation extends BucketAggregation {
 
     public class Entry extends Bucket {
         private String key;
+        private String keyAsString;
 
         public Entry(JsonObject bucket, String key, Long count) {
-            super(bucket, count);
-            this.key = key;
+            this(bucket, key, key, count);
+        }
+
+        public Entry(JsonObject bucket, String key, String keyAsString, Long count) {
+        	super(bucket, count);
+        	this.key = key;
+        	this.keyAsString = keyAsString;
         }
 
         public String getKey() {
             return key;
         }
 
+        public String getKeyAsString() {
+        	return keyAsString;
+        }
+
         @Override
         public boolean equals(Object obj) {
             if (obj == null) {
@@ -89,6 +103,7 @@ public class TermsAggregation extends BucketAggregation {
             return new EqualsBuilder()
                     .appendSuper(super.equals(obj))
                     .append(key, rhs.key)
+                    .append(keyAsString, rhs.keyAsString)
                     .isEquals();
         }
 
@@ -97,6 +112,7 @@ public class TermsAggregation extends BucketAggregation {
             return new HashCodeBuilder()
                     .append(getCount())
                     .append(getKey())
+                    .append(keyAsString)
                     .toHashCode();
         }
     }


Test patch:
diff --git a/jest-common/src/test/java/io/searchbox/core/search/aggregation/TermsAggregationTermTest.java b/jest-common/src/test/java/io/searchbox/core/search/aggregation/TermsAggregationTermTest.java
new file mode 100644
index 00000000..26bd3e6b
--- /dev/null
+++ b/jest-common/src/test/java/io/searchbox/core/search/aggregation/TermsAggregationTermTest.java
@@ -0,0 +1,69 @@
+package io.searchbox.core.search.aggregation;
+
+import static org.junit.Assert.*;
+import io.searchbox.core.BulkResult;
+import io.searchbox.core.search.aggregation.TermsAggregation.Entry;
+
+import java.util.List;
+import java.util.Map;
+
+import org.junit.Before;
+import org.junit.Test;
+
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import com.google.gson.JsonArray;
+import com.google.gson.JsonObject;
+
+public class TermsAggregationTermTest {
+
+	private static String EXPECTED_KEY_VALUE = "someKeyValue";
+	private static String EXPECTED_KEY_AS_STRING_VALUE = "someKeyAsStringValue";
+	private static long EXPECTED_DOC_COUNT_VALUE = 100L; 
+	
+	static String termObjectWithKeyAsStringField = "{\n" +
+			"    \"key\": \"" + EXPECTED_KEY_VALUE + "\",\n" +
+			"    \"key_as_string\": \"" + EXPECTED_KEY_AS_STRING_VALUE + "\",\n" +
+			"    \"doc_count\": " + EXPECTED_DOC_COUNT_VALUE + "\n" +
+			"}";
+
+	static String termObjectWithoutKeyAsStringField = "{\n" +
+			"    \"key\": \"" + EXPECTED_KEY_VALUE + "\",\n" +
+			"    \"doc_count\": " + EXPECTED_DOC_COUNT_VALUE + "\n" +
+			"}";
+	
+	static String termsAggregationContent = "{\n" +
+			"    \"doc_count_error_upper_bound\":0,\n" +
+			"    \"sum_other_doc_count\":0,\n" +
+			"    \"buckets\": [\n" +
+				termObjectWithKeyAsStringField + 
+			"    ,\n" +
+				termObjectWithoutKeyAsStringField +
+			"    ]\n" +
+			"}";
+	
+
+
+	@Test
+	public void testParseBuckets() {
+		
+		JsonObject termsAggregationJson = new Gson().fromJson(termsAggregationContent, JsonObject.class);
+		TermsAggregation termsAggregation = new TermsAggregation("termsAggregation", termsAggregationJson);
+		List<Entry> buckets = termsAggregation.getBuckets();
+		assertNotNull(buckets);
+		assertEquals(2, buckets.size());
+		// Test for entry *with* key_as_value present
+		Entry entryWithKeyAsString = buckets.get(0);
+		assertEquals(EXPECTED_KEY_VALUE, entryWithKeyAsString.getKey());
+		assertEquals(EXPECTED_KEY_AS_STRING_VALUE, entryWithKeyAsString.getKeyAsString());
+		assertTrue(EXPECTED_DOC_COUNT_VALUE == entryWithKeyAsString.getCount());
+		// Test for entry *without* key_as_value present
+		Entry entryWithoutKeyAsString = buckets.get(1);
+		assertEquals(EXPECTED_KEY_VALUE, entryWithoutKeyAsString.getKey());
+		// If key_as_string wasn't populated, return key value
+		assertEquals(EXPECTED_KEY_VALUE, entryWithoutKeyAsString.getKeyAsString());
+		assertTrue(EXPECTED_DOC_COUNT_VALUE == entryWithoutKeyAsString.getCount());
+		
+	}
+
+}