BAEL-1324 A Simple Tagging Implementation with Elasticsearch (#3464)

* Christopher Franklin A Simple Tagging Implementation with Elasticsearch

Modifying the existing Spring Data Elasticsearch example to use the tags
already on the model. Also added a number of tests as examples of how to
use the tags.
This commit is contained in:
christopherfranklin 2018-01-23 12:29:31 -05:00 committed by Predrag Maric
parent af3edc477d
commit 9f1429b067
5 changed files with 59 additions and 6 deletions

View File

@ -1,12 +1,13 @@
package com.baeldung.spring.data.es.repository;
import com.baeldung.spring.data.es.model.Article;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.annotations.Query;
import org.springframework.data.elasticsearch.repository.ElasticsearchRepository;
import org.springframework.stereotype.Repository;
import com.baeldung.spring.data.es.model.Article;
@Repository
public interface ArticleRepository extends ElasticsearchRepository<Article, String> {
@ -14,4 +15,10 @@ public interface ArticleRepository extends ElasticsearchRepository<Article, Stri
@Query("{\"bool\": {\"must\": [{\"match\": {\"authors.name\": \"?0\"}}]}}")
Page<Article> findByAuthorsNameUsingCustomQuery(String name, Pageable pageable);
@Query("{\"bool\": {\"must\": {\"match_all\": {}}, \"filter\": {\"term\": {\"tags\": \"?0\" }}}}")
Page<Article> findByFilteredTagQuery(String tag, Pageable pageable);
@Query("{\"bool\": {\"must\": {\"match\": {\"authors.name\": \"?0\"}}, \"filter\": {\"term\": {\"tags\": \"?1\" }}}}")
Page<Article> findByAuthorsNameAndFilteredTagQuery(String name, String tag, Pageable pageable);
}

View File

@ -1,9 +1,10 @@
package com.baeldung.spring.data.es.service;
import com.baeldung.spring.data.es.model.Article;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import com.baeldung.spring.data.es.model.Article;
public interface ArticleService {
Article save(Article article);
@ -15,6 +16,10 @@ public interface ArticleService {
Page<Article> findByAuthorNameUsingCustomQuery(String name, Pageable pageable);
Page<Article> findByFilteredTagQuery(String tag, Pageable pageable);
Page<Article> findByAuthorsNameAndFilteredTagQuery(String name, String tag, Pageable pageable);
long count();
void delete(Article article);

View File

@ -1,12 +1,13 @@
package com.baeldung.spring.data.es.service;
import com.baeldung.spring.data.es.repository.ArticleRepository;
import com.baeldung.spring.data.es.model.Article;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import com.baeldung.spring.data.es.model.Article;
import com.baeldung.spring.data.es.repository.ArticleRepository;
@Service
public class ArticleServiceImpl implements ArticleService {
@ -42,6 +43,16 @@ public class ArticleServiceImpl implements ArticleService {
return articleRepository.findByAuthorsNameUsingCustomQuery(name, pageable);
}
@Override
public Page<Article> findByFilteredTagQuery(String tag, Pageable pageable) {
return articleRepository.findByFilteredTagQuery(tag, pageable);
}
@Override
public Page<Article> findByAuthorsNameAndFilteredTagQuery(String name, String tag, Pageable pageable) {
return articleRepository.findByAuthorsNameAndFilteredTagQuery(name, tag, pageable);
}
@Override
public long count() {
return articleRepository.count();

View File

@ -46,14 +46,22 @@ public class ElasticSearchIntegrationTest {
Article article = new Article("Spring Data Elasticsearch");
article.setAuthors(asList(johnSmith, johnDoe));
article.setTags("elasticsearch", "spring data");
articleService.save(article);
article = new Article("Search engines");
article.setAuthors(asList(johnDoe));
article.setTags("search engines", "tutorial");
articleService.save(article);
article = new Article("Second Article About Elasticsearch");
article.setAuthors(asList(johnSmith));
article.setTags("elasticsearch", "spring data");
articleService.save(article);
article = new Article("Elasticsearch Tutorial");
article.setAuthors(asList(johnDoe));
article.setTags("elasticsearch");
articleService.save(article);
}
@ -78,12 +86,22 @@ public class ElasticSearchIntegrationTest {
@Test
public void givenCustomQuery_whenSearchByAuthorsName_thenArticleIsFound() {
final Page<Article> articleByAuthorName = articleService.findByAuthorNameUsingCustomQuery("Smith", new PageRequest(0, 10));
assertEquals(2L, articleByAuthorName.getTotalElements());
}
final Page<Article> articleByAuthorName = articleService
.findByAuthorNameUsingCustomQuery("John Smith", new PageRequest(0, 10));
@Test
public void givenTagFilterQuery_whenSearchByTag_thenArticleIsFound() {
final Page<Article> articleByAuthorName = articleService.findByFilteredTagQuery("elasticsearch", new PageRequest(0, 10));
assertEquals(3L, articleByAuthorName.getTotalElements());
}
@Test
public void givenTagFilterQuery_whenSearchByAuthorsName_thenArticleIsFound() {
final Page<Article> articleByAuthorName = articleService.findByAuthorsNameAndFilteredTagQuery("Doe", "elasticsearch", new PageRequest(0, 10));
assertEquals(2L, articleByAuthorName.getTotalElements());
}
@Test
public void givenPersistedArticles_whenUseRegexQuery_thenRightArticlesFound() {

View File

@ -191,4 +191,16 @@ public class ElasticSearchQueryIntegrationTest {
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(2, articles.size());
}
@Test
public void givenBoolQuery_whenQueryByAuthorsName_thenFoundArticlesByThatAuthorAndFilteredTag() {
final QueryBuilder builder = boolQuery().must(nestedQuery("authors", boolQuery().must(termQuery("authors.name", "doe"))))
.filter(termQuery("tags", "elasticsearch"));
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder)
.build();
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
assertEquals(2, articles.size());
}
}