diff --git a/pom.xml b/pom.xml
index 85090a338..5b728179a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -133,10 +133,10 @@
org.codehaus.mojo
wagon-maven-plugin
-
- org.asciidoctor
- asciidoctor-maven-plugin
-
+
+ org.asciidoctor
+ asciidoctor-maven-plugin
+
diff --git a/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java
new file mode 100644
index 000000000..ca2ca2f6e
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/annotations/CompletionField.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.elasticsearch.annotations;
+
+import java.lang.annotation.*;
+
+/**
+ * Based on the reference doc - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters-completion.html
+ *
+ * @author Mewes Kochheim
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+@Documented
+public @interface CompletionField {
+
+ String searchAnalyzer() default "simple";
+
+ String indexAnalyzer() default "simple";
+
+ boolean payloads() default false;
+
+ boolean preserveSeparators() default true;
+
+ boolean preservePositionIncrements() default true;
+
+ int maxInputLength() default 50;
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java
index 0d6d91810..4638edaa5 100755
--- a/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/ElasticsearchTemplate.java
@@ -51,6 +51,9 @@ import org.elasticsearch.action.mlt.MoreLikeThisRequestBuilder;
import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.search.SearchType;
+import org.elasticsearch.action.suggest.SuggestRequest;
+import org.elasticsearch.action.suggest.SuggestRequestBuilder;
+import org.elasticsearch.action.suggest.SuggestResponse;
import org.elasticsearch.action.update.UpdateRequestBuilder;
import org.elasticsearch.action.update.UpdateResponse;
import org.elasticsearch.client.Client;
@@ -60,6 +63,7 @@ import org.elasticsearch.cluster.metadata.MappingMetaData;
import org.elasticsearch.common.collect.ImmutableOpenMap;
import org.elasticsearch.common.collect.MapBuilder;
import org.elasticsearch.common.unit.TimeValue;
+import org.elasticsearch.common.xcontent.ToXContent;
import org.elasticsearch.common.xcontent.XContentBuilder;
import org.elasticsearch.index.query.FilterBuilder;
import org.elasticsearch.index.query.QueryBuilder;
@@ -70,6 +74,7 @@ import org.elasticsearch.search.facet.FacetBuilder;
import org.elasticsearch.search.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortOrder;
+import org.elasticsearch.search.suggest.SuggestBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
@@ -976,4 +981,14 @@ public class ElasticsearchTemplate implements ElasticsearchOperations, Applicati
return stringBuilder.toString();
}
+
+ public SuggestResponse suggest(SuggestBuilder.SuggestionBuilder> suggestion, String... indices) {
+ SuggestRequestBuilder suggestRequestBuilder = client.prepareSuggest(indices);
+ suggestRequestBuilder.addSuggestion(suggestion);
+ return suggestRequestBuilder.execute().actionGet();
+ }
+
+ public SuggestResponse suggest(SuggestBuilder.SuggestionBuilder> suggestion, Class clazz) {
+ return suggest(suggestion, retrieveIndexNameFromPersistentEntity(clazz));
+ }
}
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java
index ce83ee402..78f14187e 100644
--- a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java
+++ b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java
@@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
import org.springframework.core.GenericCollectionTypeResolver;
import org.springframework.data.annotation.Transient;
import org.springframework.data.elasticsearch.annotations.*;
+import org.springframework.data.elasticsearch.core.completion.Completion;
import org.springframework.data.elasticsearch.core.facet.FacetRequest;
import org.springframework.data.elasticsearch.core.geo.GeoPoint;
import org.springframework.data.mapping.model.SimpleTypeHolder;
@@ -55,7 +56,8 @@ class MappingBuilder {
public static final String INDEX_VALUE_NOT_ANALYZED = "not_analyzed";
public static final String TYPE_VALUE_STRING = "string";
- public static final String TYPE_VALUE_GEO_POINT = "geo_point";
+ public static final String TYPE_VALUE_GEO_POINT = "geo_point";
+ public static final String TYPE_VALUE_COMPLETION = "completion";
private static SimpleTypeHolder SIMPLE_TYPE_HOLDER = new SimpleTypeHolder();
@@ -94,10 +96,11 @@ class MappingBuilder {
continue;
}
- boolean isGeoField = isGeoField(field);
+ boolean isGeoField = isGeoField(field);
+ boolean isCompletionField = isCompletionField(field);
Field singleField = field.getAnnotation(Field.class);
- if (!isGeoField && isEntity(field) && isAnnotated(field)) {
+ if (!isGeoField && !isCompletionField && isEntity(field) && isAnnotated(field)) {
if (singleField == null) {
continue;
}
@@ -110,9 +113,13 @@ class MappingBuilder {
MultiField multiField = field.getAnnotation(MultiField.class);
- if (isGeoField) {
- applyGeoPointFieldMapping(xContentBuilder, field);
- }
+ if (isGeoField) {
+ applyGeoPointFieldMapping(xContentBuilder, field);
+ }
+
+ if (isCompletionField) {
+ applyCompletionFieldMapping(xContentBuilder, field);
+ }
if (isRootObject && singleField != null && isIdField(field, idFieldName)) {
applyDefaultIdFieldMapping(xContentBuilder, field);
@@ -153,6 +160,12 @@ class MappingBuilder {
.endObject();
}
+ private static void applyCompletionFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field) throws IOException {
+ xContentBuilder.startObject(field.getName());
+ xContentBuilder.field(FIELD_TYPE, TYPE_VALUE_COMPLETION)
+ .endObject();
+ }
+
private static void applyDefaultIdFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field)
throws IOException {
xContentBuilder.startObject(field.getName())
@@ -304,7 +317,11 @@ class MappingBuilder {
return fieldAnnotation != null && (FieldType.Nested == fieldAnnotation.type() || FieldType.Object == fieldAnnotation.type());
}
- private static boolean isGeoField(java.lang.reflect.Field field) {
- return field.getType() == GeoPoint.class || field.getAnnotation(GeoPointField.class) != null;
- }
-}
+ private static boolean isGeoField(java.lang.reflect.Field field) {
+ return field.getType() == GeoPoint.class || field.getAnnotation(GeoPointField.class) != null;
+ }
+
+ private static boolean isCompletionField(java.lang.reflect.Field field) {
+ return field.getType() == Completion.class;
+ }
+}
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java.rej b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java.rej
new file mode 100644
index 000000000..23019c89c
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java.rej
@@ -0,0 +1,78 @@
+diff a/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java b/src/main/java/org/springframework/data/elasticsearch/core/MappingBuilder.java (rejected hunks)
+@@ -29,6 +29,7 @@ import org.elasticsearch.common.xcontent.XContentBuilder;
+ import org.springframework.core.GenericCollectionTypeResolver;
+ import org.springframework.data.annotation.Transient;
+ import org.springframework.data.elasticsearch.annotations.*;
++import org.springframework.data.elasticsearch.core.completion.Completion;
+ import org.springframework.data.elasticsearch.core.facet.FacetRequest;
+ import org.springframework.data.elasticsearch.core.geo.GeoPoint;
+ import org.springframework.data.mapping.model.SimpleTypeHolder;
+@@ -55,7 +56,8 @@ class MappingBuilder {
+
+ public static final String INDEX_VALUE_NOT_ANALYZED = "not_analyzed";
+ public static final String TYPE_VALUE_STRING = "string";
+- public static final String TYPE_VALUE_GEO_POINT = "geo_point";
++ public static final String TYPE_VALUE_GEO_POINT = "geo_point";
++ public static final String TYPE_VALUE_COMPLETION = "completion";
+
+ private static SimpleTypeHolder SIMPLE_TYPE_HOLDER = new SimpleTypeHolder();
+
+@@ -94,10 +96,11 @@ class MappingBuilder {
+ continue;
+ }
+
+- boolean isGeoField = isGeoField(field);
++ boolean isGeoField = isGeoField(field);
++ boolean isCompletionField = isCompletionField(field);
+
+ Field singleField = field.getAnnotation(Field.class);
+- if (!isGeoField && isEntity(field) && isAnnotated(field)) {
++ if (!isGeoField && !isCompletionField && isEntity(field) && isAnnotated(field)) {
+ if (singleField == null) {
+ continue;
+ }
+@@ -110,9 +113,13 @@ class MappingBuilder {
+
+ MultiField multiField = field.getAnnotation(MultiField.class);
+
+- if (isGeoField) {
+- applyGeoPointFieldMapping(xContentBuilder, field);
+- }
++ if (isGeoField) {
++ applyGeoPointFieldMapping(xContentBuilder, field);
++ }
++
++ if (isCompletionField) {
++ applyCompletionFieldMapping(xContentBuilder, field);
++ }
+
+ if (isRootObject && singleField != null && isIdField(field, idFieldName)) {
+ applyDefaultIdFieldMapping(xContentBuilder, field);
+@@ -153,6 +160,12 @@ class MappingBuilder {
+ .endObject();
+ }
+
++ private static void applyCompletionFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field) throws IOException {
++ xContentBuilder.startObject(field.getName());
++ xContentBuilder.field(FIELD_TYPE, TYPE_VALUE_COMPLETION)
++ .endObject();
++ }
++
+ private static void applyDefaultIdFieldMapping(XContentBuilder xContentBuilder, java.lang.reflect.Field field)
+ throws IOException {
+ xContentBuilder.startObject(field.getName())
+@@ -304,7 +317,11 @@ class MappingBuilder {
+ return fieldAnnotation != null && (FieldType.Nested == fieldAnnotation.type() || FieldType.Object == fieldAnnotation.type());
+ }
+
+- private static boolean isGeoField(java.lang.reflect.Field field) {
+- return field.getType() == GeoPoint.class || field.getAnnotation(GeoPointField.class) != null;
+- }
++ private static boolean isGeoField(java.lang.reflect.Field field) {
++ return field.getType() == GeoPoint.class || field.getAnnotation(GeoPointField.class) != null;
++ }
++
++ private static boolean isCompletionField(java.lang.reflect.Field field) {
++ return field.getType() == Completion.class;
++ }
+ }
diff --git a/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java b/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java
new file mode 100644
index 000000000..a1d86d17c
--- /dev/null
+++ b/src/main/java/org/springframework/data/elasticsearch/core/completion/Completion.java
@@ -0,0 +1,57 @@
+package org.springframework.data.elasticsearch.core.completion;
+
+import com.fasterxml.jackson.annotation.JsonInclude;
+
+/**
+ * Based on the reference doc - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/search-suggesters-completion.html
+ *
+ * @author Mewes Kochheim
+ */
+@JsonInclude(value = JsonInclude.Include.NON_NULL)
+public class Completion {
+
+ private String[] input;
+ private String output;
+ private Integer weight;
+ private Object payload;
+
+ private Completion() {
+ //required by mapper to instantiate object
+ }
+
+ public Completion(String[] input) {
+ this.input = input;
+ }
+
+ public String[] getInput() {
+ return input;
+ }
+
+ public void setInput(String[] input) {
+ this.input = input;
+ }
+
+ public String getOutput() {
+ return output;
+ }
+
+ public void setOutput(String output) {
+ this.output = output;
+ }
+
+ public Object getPayload() {
+ return payload;
+ }
+
+ public void setPayload(Object payload) {
+ this.payload = payload;
+ }
+
+ public Integer getWeight() {
+ return weight;
+ }
+
+ public void setWeight(Integer weight) {
+ this.weight = weight;
+ }
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/AnnotatedCompletionEntity.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/AnnotatedCompletionEntity.java
new file mode 100644
index 000000000..4d6a9c38e
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/AnnotatedCompletionEntity.java
@@ -0,0 +1,50 @@
+package org.springframework.data.elasticsearch.core.completion;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.elasticsearch.annotations.CompletionField;
+import org.springframework.data.elasticsearch.annotations.Document;
+
+/**
+ * @author Mewes Kochheim
+ */
+@Document(indexName = "test-completion-index", type = "annotated-completion-type", indexStoreType = "memory", shards = 1, replicas = 0, refreshInterval = "-1")
+public class AnnotatedCompletionEntity {
+
+ @Id
+ private String id;
+ private String name;
+
+ @CompletionField(payloads = true, maxInputLength = 100)
+ private Completion suggest;
+
+ private AnnotatedCompletionEntity() {
+ }
+
+ public AnnotatedCompletionEntity(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Completion getSuggest() {
+ return suggest;
+ }
+
+ public void setSuggest(Completion suggest) {
+ this.suggest = suggest;
+ }
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/AnnotatedCompletionEntityBuilder.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/AnnotatedCompletionEntityBuilder.java
new file mode 100644
index 000000000..497504560
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/AnnotatedCompletionEntityBuilder.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2013-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.elasticsearch.core.completion;
+
+import org.springframework.data.elasticsearch.core.query.IndexQuery;
+
+/**
+ * @author Franck Marchand
+ * @author Mohsin Husen
+ * @author Mewes Kochheim
+ */
+public class AnnotatedCompletionEntityBuilder {
+
+ private CompletionEntity result;
+
+ public AnnotatedCompletionEntityBuilder(String id) {
+ result = new CompletionEntity(id);
+ }
+
+ public AnnotatedCompletionEntityBuilder name(String name) {
+ result.setName(name);
+ return this;
+ }
+
+ public AnnotatedCompletionEntityBuilder suggest(String[] input) {
+ return suggest(input, null, null, null);
+ }
+
+ public AnnotatedCompletionEntityBuilder suggest(String[] input, String output) {
+ return suggest(input, output, null, null);
+ }
+
+ public AnnotatedCompletionEntityBuilder suggest(String[] input, String output, Object payload) {
+ return suggest(input, output, payload, null);
+ }
+
+ public AnnotatedCompletionEntityBuilder suggest(String[] input, String output, Object payload, Integer weight) {
+ Completion suggest = new Completion(input);
+ suggest.setOutput(output);
+ suggest.setPayload(payload);
+ suggest.setWeight(weight);
+
+ result.setSuggest(suggest);
+ return this;
+ }
+
+ public CompletionEntity build() {
+ return result;
+ }
+
+ public IndexQuery buildIndex() {
+ IndexQuery indexQuery = new IndexQuery();
+ indexQuery.setId(result.getId());
+ indexQuery.setObject(result);
+ return indexQuery;
+ }
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionAnnotatedEntity.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionAnnotatedEntity.java
new file mode 100644
index 000000000..de3b69ee7
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionAnnotatedEntity.java
@@ -0,0 +1,52 @@
+package org.springframework.data.elasticsearch.core.completion;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.elasticsearch.annotations.CompletionField;
+import org.springframework.data.elasticsearch.annotations.Document;
+
+/**
+ * @author Franck Marchand
+ * @author Mohsin Husen
+ * @author Mewes Kochheim
+ */
+@Document(indexName = "test-completion-index", type = "completion-annotation-type", indexStoreType = "memory", shards = 1, replicas = 0, refreshInterval = "-1")
+public class CompletionAnnotatedEntity {
+
+ @Id
+ private String id;
+ private String name;
+
+ @CompletionField(payloads = true)
+ private Completion suggest;
+
+ private CompletionAnnotatedEntity() {
+ }
+
+ public CompletionAnnotatedEntity(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Completion getSuggest() {
+ return suggest;
+ }
+
+ public void setSuggest(Completion suggest) {
+ this.suggest = suggest;
+ }
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionEntity.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionEntity.java
new file mode 100644
index 000000000..bc049b643
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionEntity.java
@@ -0,0 +1,48 @@
+package org.springframework.data.elasticsearch.core.completion;
+
+import org.springframework.data.annotation.Id;
+import org.springframework.data.elasticsearch.annotations.Document;
+
+/**
+ * @author Mewes Kochheim
+ */
+@Document(indexName = "test-completion-index", type = "completion-type", indexStoreType = "memory", shards = 1, replicas = 0, refreshInterval = "-1")
+public class CompletionEntity {
+
+ @Id
+ private String id;
+ private String name;
+
+ private Completion suggest;
+
+ private CompletionEntity() {
+ }
+
+ public CompletionEntity(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public void setName(String name) {
+ this.name = name;
+ }
+
+ public Completion getSuggest() {
+ return suggest;
+ }
+
+ public void setSuggest(Completion suggest) {
+ this.suggest = suggest;
+ }
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionEntityAnnotatedBuilder.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionEntityAnnotatedBuilder.java
new file mode 100644
index 000000000..7fa96cebc
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionEntityAnnotatedBuilder.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2013-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.elasticsearch.core.completion;
+
+import org.springframework.data.elasticsearch.core.query.IndexQuery;
+
+/**
+ * @author Franck Marchand
+ * @author Mohsin Husen
+ * @author Mewes Kochheim
+ */
+public class CompletionEntityAnnotatedBuilder {
+
+ private CompletionAnnotatedEntity result;
+
+ public CompletionEntityAnnotatedBuilder(String id) {
+ result = new CompletionAnnotatedEntity(id);
+ }
+
+ public CompletionEntityAnnotatedBuilder name(String name) {
+ result.setName(name);
+ return this;
+ }
+
+ public CompletionEntityAnnotatedBuilder suggest(String[] input) {
+ return suggest(input, null, null, null);
+ }
+
+ public CompletionEntityAnnotatedBuilder suggest(String[] input, String output) {
+ return suggest(input, output, null, null);
+ }
+
+ public CompletionEntityAnnotatedBuilder suggest(String[] input, String output, Object payload) {
+ return suggest(input, output, payload, null);
+ }
+
+ public CompletionEntityAnnotatedBuilder suggest(String[] input, String output, Object payload, Integer weight) {
+ Completion suggest = new Completion(input);
+ if (output != null) {
+ suggest.setOutput(output);
+ }
+ if (payload != null) {
+ suggest.setPayload(payload);
+ }
+ if (weight != null) {
+ suggest.setWeight(weight);
+ }
+ result.setSuggest(suggest);
+ return this;
+ }
+
+ public CompletionAnnotatedEntity build() {
+ return result;
+ }
+
+ public IndexQuery buildIndex() {
+ IndexQuery indexQuery = new IndexQuery();
+ indexQuery.setId(result.getId());
+ indexQuery.setObject(result);
+ return indexQuery;
+ }
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionEntityBuilder.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionEntityBuilder.java
new file mode 100644
index 000000000..bebb52ed2
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/CompletionEntityBuilder.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2013-2014 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.elasticsearch.core.completion;
+
+import org.springframework.data.elasticsearch.core.query.IndexQuery;
+
+/**
+ * @author Mewes Kochheim
+ */
+public class CompletionEntityBuilder {
+
+ private CompletionEntity result;
+
+ public CompletionEntityBuilder(String id) {
+ result = new CompletionEntity(id);
+ }
+
+ public CompletionEntityBuilder name(String name) {
+ result.setName(name);
+ return this;
+ }
+
+ public CompletionEntityBuilder suggest(String[] input) {
+ return suggest(input, null, null, null);
+ }
+
+ public CompletionEntityBuilder suggest(String[] input, String output) {
+ return suggest(input, output, null, null);
+ }
+
+ public CompletionEntityBuilder suggest(String[] input, String output, Object payload) {
+ return suggest(input, output, payload, null);
+ }
+
+ public CompletionEntityBuilder suggest(String[] input, String output, Object payload, Integer weight) {
+ Completion suggest = new Completion(input);
+ suggest.setOutput(output);
+ suggest.setPayload(payload);
+ suggest.setWeight(weight);
+
+ result.setSuggest(suggest);
+ return this;
+ }
+
+ public CompletionEntity build() {
+ return result;
+ }
+
+ public IndexQuery buildIndex() {
+ IndexQuery indexQuery = new IndexQuery();
+ indexQuery.setId(result.getId());
+ indexQuery.setObject(result);
+ return indexQuery;
+ }
+}
diff --git a/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java
new file mode 100644
index 000000000..eddd1d27a
--- /dev/null
+++ b/src/test/java/org/springframework/data/elasticsearch/core/completion/ElasticsearchTemplateCompletionTests.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2013 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.data.elasticsearch.core.completion;
+
+import org.elasticsearch.action.suggest.SuggestResponse;
+import org.elasticsearch.search.suggest.completion.CompletionSuggestion;
+import org.elasticsearch.search.suggest.completion.CompletionSuggestionFuzzyBuilder;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
+import org.springframework.data.elasticsearch.core.query.IndexQuery;
+import org.springframework.data.elasticsearch.entities.NonDocumentEntity;
+import org.springframework.test.context.ContextConfiguration;
+import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertEquals;
+
+/**
+ * @author Rizwan Idrees
+ * @author Mohsin Husen
+ * @author Franck Marchand
+ * @author Artur Konczak
+ * @author Mewes Kochheim
+ */
+@RunWith(SpringJUnit4ClassRunner.class)
+@ContextConfiguration("classpath:elasticsearch-template-test.xml")
+public class ElasticsearchTemplateCompletionTests {
+
+ @Autowired
+ private ElasticsearchTemplate elasticsearchTemplate;
+
+ private void loadCompletionObjectEntities() {
+ elasticsearchTemplate.deleteIndex(CompletionEntity.class);
+ elasticsearchTemplate.createIndex(CompletionEntity.class);
+ elasticsearchTemplate.refresh(CompletionEntity.class, true);
+ elasticsearchTemplate.putMapping(CompletionEntity.class);
+
+ List indexQueries = new ArrayList();
+ indexQueries.add(new CompletionEntityBuilder("1").name("Rizwan Idrees").suggest(new String[]{"Rizwan Idrees"}).buildIndex());
+ indexQueries.add(new CompletionEntityBuilder("2").name("Franck Marchand").suggest(new String[]{"Franck", "Marchand"}).buildIndex());
+ indexQueries.add(new CompletionEntityBuilder("3").name("Mohsin Husen").suggest(new String[]{"Mohsin", "Husen"}, "Mohsin Husen").buildIndex());
+ indexQueries.add(new CompletionEntityBuilder("4").name("Artur Konczak").suggest(new String[]{"Artur", "Konczak"}, "Artur Konczak", null, 60).buildIndex());
+
+ elasticsearchTemplate.bulkIndex(indexQueries);
+ elasticsearchTemplate.refresh(CompletionEntity.class, true);
+ }
+
+ private void loadAnnotatedCompletionObjectEntities() {
+ elasticsearchTemplate.deleteIndex(AnnotatedCompletionEntity.class);
+ elasticsearchTemplate.createIndex(AnnotatedCompletionEntity.class);
+ elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class, true);
+ elasticsearchTemplate.putMapping(AnnotatedCompletionEntity.class);
+
+ NonDocumentEntity nonDocumentEntity = new NonDocumentEntity();
+ nonDocumentEntity.setSomeField1("foo");
+ nonDocumentEntity.setSomeField2("bar");
+
+ List indexQueries = new ArrayList();
+ indexQueries.add(new AnnotatedCompletionEntityBuilder("1").name("Franck Marchand").suggest(new String[]{"Franck", "Marchand"}).buildIndex());
+ indexQueries.add(new AnnotatedCompletionEntityBuilder("2").name("Mohsin Husen").suggest(new String[]{"Mohsin", "Husen"}, "Mohsin Husen").buildIndex());
+ indexQueries.add(new AnnotatedCompletionEntityBuilder("3").name("Rizwan Idrees").suggest(new String[]{"Rizwan", "Idrees"}, "Rizwan Idrees", "Payload test").buildIndex());
+ indexQueries.add(new AnnotatedCompletionEntityBuilder("4").name("Artur Konczak").suggest(new String[]{"Artur", "Konczak"}, "Artur Konczak", nonDocumentEntity, 60).buildIndex());
+
+ elasticsearchTemplate.bulkIndex(indexQueries);
+ elasticsearchTemplate.refresh(AnnotatedCompletionEntity.class, true);
+ }
+
+ @Test
+ public void shouldPutMappingForGivenEntity() throws Exception {
+ //given
+ Class entity = CompletionEntity.class;
+ elasticsearchTemplate.createIndex(entity);
+
+ //when
+ assertThat(elasticsearchTemplate.putMapping(entity), is(true));
+ }
+
+ @Test
+ public void shouldFindSuggestionsForGivenCriteriaQueryUsingCompletionObjectEntity() {
+ //given
+ loadCompletionObjectEntities();
+ CompletionSuggestionFuzzyBuilder completionSuggestionFuzzyBuilder = new CompletionSuggestionFuzzyBuilder("test-suggest")
+ .text("m")
+ .field("suggest");
+
+ //when
+ SuggestResponse suggestResponse = elasticsearchTemplate.suggest(completionSuggestionFuzzyBuilder, CompletionEntity.class);
+ CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
+ List options = completionSuggestion.getEntries().get(0).getOptions();
+
+ //then
+ assertThat(options.size(), is(2));
+ assertEquals("Marchand", options.get(0).getText().string());
+ }
+
+ @Test
+ public void shouldFindSuggestionsForGivenCriteriaQueryUsingloadAnnotatedCompletionObjectEntity() {
+ //given
+ loadCompletionObjectEntities();
+ CompletionSuggestionFuzzyBuilder completionSuggestionFuzzyBuilder = new CompletionSuggestionFuzzyBuilder("test-suggest")
+ .text("m")
+ .field("suggest");
+
+ //when
+ SuggestResponse suggestResponse = elasticsearchTemplate.suggest(completionSuggestionFuzzyBuilder, CompletionEntity.class);
+ CompletionSuggestion completionSuggestion = suggestResponse.getSuggest().getSuggestion("test-suggest");
+ List options = completionSuggestion.getEntries().get(0).getOptions();
+
+ //then
+ assertThat(options.size(), is(2));
+ assertEquals("Marchand", options.get(0).getText().string());
+ }
+}