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:
parent
af3edc477d
commit
9f1429b067
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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() {
|
||||
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue