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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user