/* * Copyright 2014-2016 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;import static org.apache.commons.lang.RandomStringUtils.*;import static org.elasticsearch.index.query.QueryBuilders.*;import static org.hamcrest.Matchers.*;import static org.junit.Assert.*;import static org.springframework.data.elasticsearch.utils.IndexBuilder.*;import java.util.*;import org.apache.commons.lang.StringUtils;import org.elasticsearch.action.get.MultiGetItemResponse;import org.elasticsearch.action.get.MultiGetResponse;import org.elasticsearch.action.index.IndexRequest;import org.elasticsearch.action.search.SearchResponse;import org.elasticsearch.index.engine.DocumentMissingException;import org.elasticsearch.script.Script;import org.elasticsearch.script.ScriptService;import org.elasticsearch.search.SearchHit;import org.elasticsearch.search.highlight.HighlightBuilder;import org.elasticsearch.search.sort.FieldSortBuilder;import org.elasticsearch.search.sort.SortOrder;import org.hamcrest.Matchers;import org.junit.Before;import org.junit.Ignore;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.PageRequest;import org.springframework.data.domain.Pageable;import org.springframework.data.domain.Sort;import org.springframework.data.elasticsearch.ElasticsearchException;import org.springframework.data.elasticsearch.annotations.Document;import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;import org.springframework.data.elasticsearch.core.query.*;import org.springframework.data.elasticsearch.entities.*;import org.springframework.data.util.CloseableIterator;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/** * @author Rizwan Idrees * @author Mohsin Husen * @author Franck Marchand * @author Abdul Mohammed * @author Kevin Leturc * @author Mason Chan */@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration("classpath:elasticsearch-template-test.xml")public class ElasticsearchTemplateTests { private static final String INDEX_NAME = "test-index"; private static final String INDEX_1_NAME = "test-index-1"; private static final String INDEX_2_NAME = "test-index-2"; private static final String TYPE_NAME = "test-type"; @Autowired private ElasticsearchTemplate elasticsearchTemplate; @Before public void before() { elasticsearchTemplate.deleteIndex(SampleEntity.class); elasticsearchTemplate.createIndex(SampleEntity.class); elasticsearchTemplate.deleteIndex(INDEX_1_NAME); elasticsearchTemplate.deleteIndex(INDEX_2_NAME); elasticsearchTemplate.deleteIndex(UseServerConfigurationEntity.class); elasticsearchTemplate.refresh(SampleEntity.class); } /* DATAES-106 */ @Test public void shouldReturnCountForGivenCriteriaQuery() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()); // when long count = elasticsearchTemplate.count(criteriaQuery, SampleEntity.class); // then assertThat(count, is(equalTo(1L))); } @Test public void shouldReturnCountForGivenSearchQuery() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when long count = elasticsearchTemplate.count(searchQuery, SampleEntity.class); // then assertThat(count, is(equalTo(1L))); } @Test public void shouldReturnObjectForGivenId() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); // when GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(getQuery, SampleEntity.class); // then assertNotNull("entity can't be null....", sampleEntity1); assertEquals(sampleEntity, sampleEntity1); } @Test public void shouldReturnObjectsForGivenIdsUsingMultiGet() { // given List indexQueries = new ArrayList (); // first document String documentId = randomNumeric(5); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); // second document String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some message") .version(System.currentTimeMillis()).build(); indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); // when SearchQuery query = new NativeSearchQueryBuilder().withIds(Arrays.asList(documentId, documentId2)).build(); LinkedList sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class); // then assertThat(sampleEntities.size(), is(equalTo(2))); assertEquals(sampleEntities.get(0), sampleEntity1); assertEquals(sampleEntities.get(1), sampleEntity2); } @Test public void shouldReturnObjectsForGivenIdsUsingMultiGetWithFields() { // given List indexQueries = new ArrayList (); // first document String documentId = randomNumeric(5); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId) .message("some message") .type("type1") .version(System.currentTimeMillis()).build(); // second document String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2) .message("some message") .type("type2") .version(System.currentTimeMillis()).build(); indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); // when SearchQuery query = new NativeSearchQueryBuilder() .withIds(Arrays.asList(documentId, documentId2)) .withFields("message", "type") .build(); LinkedList sampleEntities = elasticsearchTemplate.multiGet(query, SampleEntity.class, new MultiGetResultMapper() { @Override public LinkedList mapResults(MultiGetResponse responses, Class clazz) { LinkedList list = new LinkedList (); for (MultiGetItemResponse response : responses.getResponses()) { SampleEntity entity = new SampleEntity(); entity.setId(response.getResponse().getId()); entity.setMessage((String) response.getResponse().getField("message").getValue()); entity.setType((String) response.getResponse().getField("type").getValue()); list.add((T) entity); } return list; } }); // then assertThat(sampleEntities.size(), is(equalTo(2))); } @Test public void shouldReturnPageForGivenSearchQuery() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); // when Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); // then assertThat(sampleEntities, is(notNullValue())); assertThat(sampleEntities.getTotalElements(), greaterThanOrEqualTo(1L)); } @Test public void shouldDoBulkIndex() { // given List indexQueries = new ArrayList (); // first document String documentId = randomNumeric(5); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); // second document String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2).message("some message") .version(System.currentTimeMillis()).build(); indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2)); // when elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); // then SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements(), is(equalTo(2L))); } @Test public void shouldDoBulkUpdate() { //given String documentId = randomNumeric(5); String messageBeforeUpdate = "some test message"; String messageAfterUpdate = "test message"; SampleEntity sampleEntity = SampleEntity.builder().id(documentId) .message(messageBeforeUpdate) .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); IndexRequest indexRequest = new IndexRequest(); indexRequest.source("message", messageAfterUpdate); UpdateQuery updateQuery = new UpdateQueryBuilder().withId(documentId) .withClass(SampleEntity.class).withIndexRequest(indexRequest).build(); List queries = new ArrayList (); queries.add(updateQuery); // when elasticsearchTemplate.bulkUpdate(queries); //then GetQuery getQuery = new GetQuery(); getQuery.setId(documentId); SampleEntity indexedEntity = elasticsearchTemplate.queryForObject(getQuery, SampleEntity.class); assertThat(indexedEntity.getMessage(), is(messageAfterUpdate)); } @Test public void shouldDeleteDocumentForGivenId() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); // when elasticsearchTemplate.delete(INDEX_NAME, TYPE_NAME, documentId); elasticsearchTemplate.refresh(SampleEntity.class); // then SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements(), equalTo(0L)); } @Test public void shouldDeleteEntityForGivenId() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); // when elasticsearchTemplate.delete(SampleEntity.class, documentId); elasticsearchTemplate.refresh(SampleEntity.class); // then SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements(), equalTo(0L)); } @Test public void shouldDeleteDocumentForGivenQuery() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); // when DeleteQuery deleteQuery = new DeleteQuery(); deleteQuery.setQuery(termQuery("id", documentId)); elasticsearchTemplate.delete(deleteQuery, SampleEntity.class); elasticsearchTemplate.refresh(SampleEntity.class); // then SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(termQuery("id", documentId)).build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); assertThat(sampleEntities.getTotalElements(), equalTo(0L)); } @Test public void shouldFilterSearchResultsForGivenFilter() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withFilter(boolQuery().filter(termQuery("id", documentId))).build(); // when Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); // then assertThat(sampleEntities.getTotalElements(), equalTo(1L)); } @Test public void shouldSortResultsGivenSortCriteria() { // given List indexQueries = new ArrayList (); // first document String documentId = randomNumeric(5); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId) .message("abc") .rate(10) .version(System.currentTimeMillis()).build(); // second document String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2) .message("xyz") .rate(5) .version(System.currentTimeMillis()).build(); // third document String documentId3 = randomNumeric(5); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3) .message("xyz") .rate(15) .version(System.currentTimeMillis()).build(); indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").ignoreUnmapped(true).order(SortOrder.ASC)).build(); // when Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); // then assertThat(sampleEntities.getTotalElements(), equalTo(3L)); assertThat(sampleEntities.getContent().get(0).getRate(), is(sampleEntity2.getRate())); } @Test public void shouldSortResultsGivenMultipleSortCriteria() { // given List indexQueries = new ArrayList (); // first document String documentId = randomNumeric(5); SampleEntity sampleEntity1 = SampleEntity.builder().id(documentId) .message("abc") .rate(10) .version(System.currentTimeMillis()).build(); // second document String documentId2 = randomNumeric(5); SampleEntity sampleEntity2 = SampleEntity.builder().id(documentId2) .message("xyz") .rate(5) .version(System.currentTimeMillis()).build(); // third document String documentId3 = randomNumeric(5); SampleEntity sampleEntity3 = SampleEntity.builder().id(documentId3) .message("xyz") .rate(15) .version(System.currentTimeMillis()).build(); indexQueries = getIndexQueries(Arrays.asList(sampleEntity1, sampleEntity2, sampleEntity3)); elasticsearchTemplate.bulkIndex(indexQueries); elasticsearchTemplate.refresh(SampleEntity.class); SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchAllQuery()) .withSort(new FieldSortBuilder("rate").ignoreUnmapped(true).order(SortOrder.ASC)) .withSort(new FieldSortBuilder("message").ignoreUnmapped(true).order(SortOrder.ASC)).build(); // when Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); // then assertThat(sampleEntities.getTotalElements(), equalTo(3L)); assertThat(sampleEntities.getContent().get(0).getRate(), is(sampleEntity2.getRate())); assertThat(sampleEntities.getContent().get(1).getMessage(), is(sampleEntity1.getMessage())); } @Test public void shouldExecuteStringQuery() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString()); // when Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class); // then assertThat(sampleEntities.getTotalElements(), equalTo(1L)); } @Test public void shouldUseScriptedFields() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setRate(2); sampleEntity.setMessage("some message"); sampleEntity.setVersion(System.currentTimeMillis()); IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); Map params = new HashMap (); params.put("factor", 2); // when SearchQuery searchQuery = new NativeSearchQueryBuilder() .withQuery(matchAllQuery()) .withScriptField(new ScriptField("scriptedRate", new Script("doc['rate'].value * factor", ScriptService.ScriptType.INLINE, null, params))) .build(); Page sampleEntities = elasticsearchTemplate.queryForPage(searchQuery, SampleEntity.class); // then assertThat(sampleEntities.getTotalElements(), equalTo(1L)); assertThat(sampleEntities.getContent().get(0).getScriptedRate(), equalTo(4L)); } @Test public void shouldReturnPageableResultsGivenStringQuery() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), new PageRequest(0, 10)); // when Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class); // then assertThat(sampleEntities.getTotalElements(), is(greaterThanOrEqualTo(1L))); } @Test @Ignore("By default, the search request will fail if there is no mapping associated with a field. The ignore_unmapped option allows to ignore fields that have no mapping and not sort by them") public void shouldReturnSortedPageableResultsGivenStringQuery() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = new SampleEntity(); sampleEntity.setId(documentId); sampleEntity.setMessage("some message"); sampleEntity.setVersion(System.currentTimeMillis()); IndexQuery indexQuery = new IndexQuery(); indexQuery.setId(documentId); indexQuery.setObject(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(matchAllQuery().toString(), new PageRequest(0, 10), new Sort( new Sort.Order(Sort.Direction.ASC, "messsage"))); // when Page sampleEntities = elasticsearchTemplate.queryForPage(stringQuery, SampleEntity.class); // then assertThat(sampleEntities.getTotalElements(), is(greaterThanOrEqualTo(1L))); } @Test public void shouldReturnObjectMatchingGivenStringQuery() { // given String documentId = randomNumeric(5); SampleEntity sampleEntity = SampleEntity.builder().id(documentId).message("some message") .version(System.currentTimeMillis()).build(); IndexQuery indexQuery = getIndexQuery(sampleEntity); elasticsearchTemplate.index(indexQuery); elasticsearchTemplate.refresh(SampleEntity.class); StringQuery stringQuery = new StringQuery(termQuery("id", documentId).toString()); // when SampleEntity sampleEntity1 = elasticsearchTemplate.queryForObject(stringQuery, SampleEntity.class); // then assertThat(sampleEntity1, is(notNullValue())); assertThat(sampleEntity1.getId(), is(equalTo(documentId))); } @Test public void shouldCreateIndexGivenEntityClass() { // when boolean created = elasticsearchTemplate.createIndex(SampleEntity.class); final Map setting = elasticsearchTemplate.getSetting(SampleEntity.class); // then assertThat(created, is(true)); assertThat(setting.get("index.number_of_shards"), Matchers.