DATAES-91 - completion suggester support

This commit is contained in:
Felix Peters
2014-11-11 16:46:57 +01:00
committed by Artur Konczak
parent 0e37c5d36f
commit dfa0823c9a
13 changed files with 717 additions and 14 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
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<IndexQuery> indexQueries = new ArrayList<IndexQuery>();
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<CompletionSuggestion.Entry.Option> 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<CompletionSuggestion.Entry.Option> options = completionSuggestion.getEntries().get(0).getOptions();
//then
assertThat(options.size(), is(2));
assertEquals("Marchand", options.get(0).getText().string());
}
}