Merge branch 'eugenp:master' into master
This commit is contained in:
+4
-9
@@ -6,17 +6,17 @@ import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.elasticsearch.client.ClientConfiguration;
|
||||
import org.springframework.data.elasticsearch.client.RestClients;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
|
||||
import org.springframework.data.elasticsearch.config.AbstractElasticsearchConfiguration;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
|
||||
@Configuration
|
||||
@EnableElasticsearchRepositories(basePackages = "com.baeldung.spring.data.es.repository")
|
||||
@ComponentScan(basePackages = { "com.baeldung.spring.data.es.service" })
|
||||
public class Config {
|
||||
public class Config extends AbstractElasticsearchConfiguration {
|
||||
|
||||
@Bean
|
||||
RestHighLevelClient client() {
|
||||
@Override
|
||||
public RestHighLevelClient elasticsearchClient() {
|
||||
ClientConfiguration clientConfiguration = ClientConfiguration.builder()
|
||||
.connectedTo("localhost:9200")
|
||||
.build();
|
||||
@@ -24,9 +24,4 @@ public class Config {
|
||||
return RestClients.create(clientConfiguration)
|
||||
.rest();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ElasticsearchOperations elasticsearchTemplate() {
|
||||
return new ElasticsearchRestTemplate(client());
|
||||
}
|
||||
}
|
||||
|
||||
+6
-6
@@ -22,7 +22,7 @@ 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.elasticsearch.core.ElasticsearchRestTemplate;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.SearchHits;
|
||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
|
||||
@@ -41,7 +41,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
public class ElasticSearchManualTest {
|
||||
|
||||
@Autowired
|
||||
private ElasticsearchRestTemplate elasticsearchTemplate;
|
||||
private ElasticsearchOperations elasticsearchOperations;
|
||||
|
||||
@Autowired
|
||||
private ArticleRepository articleRepository;
|
||||
@@ -117,7 +117,7 @@ public class ElasticSearchManualTest {
|
||||
final Query searchQuery = new NativeSearchQueryBuilder().withFilter(regexpQuery("title", ".*data.*"))
|
||||
.build();
|
||||
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(1, articles.getTotalHits());
|
||||
}
|
||||
@@ -126,7 +126,7 @@ public class ElasticSearchManualTest {
|
||||
public void givenSavedDoc_whenTitleUpdated_thenCouldFindByUpdatedTitle() {
|
||||
final Query searchQuery = new NativeSearchQueryBuilder().withQuery(fuzzyQuery("title", "serch"))
|
||||
.build();
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(1, articles.getTotalHits());
|
||||
|
||||
@@ -147,7 +147,7 @@ public class ElasticSearchManualTest {
|
||||
|
||||
final Query searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", articleTitle).minimumShouldMatch("75%"))
|
||||
.build();
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(1, articles.getTotalHits());
|
||||
final long count = articleRepository.count();
|
||||
@@ -162,7 +162,7 @@ public class ElasticSearchManualTest {
|
||||
public void givenSavedDoc_whenOneTermMatches_thenFindByTitle() {
|
||||
final Query searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Search engines").operator(AND))
|
||||
.build();
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
assertEquals(1, articles.getTotalHits());
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -39,7 +39,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
|
||||
import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
||||
import org.springframework.data.elasticsearch.core.SearchHits;
|
||||
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;
|
||||
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
|
||||
@@ -58,7 +58,7 @@ import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
public class ElasticSearchQueryManualTest {
|
||||
|
||||
@Autowired
|
||||
private ElasticsearchRestTemplate elasticsearchTemplate;
|
||||
private ElasticsearchOperations elasticsearchOperations;
|
||||
|
||||
@Autowired
|
||||
private ArticleRepository articleRepository;
|
||||
@@ -101,7 +101,7 @@ public class ElasticSearchQueryManualTest {
|
||||
public void givenFullTitle_whenRunMatchQuery_thenDocIsFound() {
|
||||
final NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Search engines").operator(Operator.AND))
|
||||
.build();
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
assertEquals(1, articles.getTotalHits());
|
||||
}
|
||||
|
||||
@@ -110,7 +110,7 @@ public class ElasticSearchQueryManualTest {
|
||||
final NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Engines Solutions"))
|
||||
.build();
|
||||
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(1, articles.getTotalHits());
|
||||
assertEquals("Search engines", articles.getSearchHit(0)
|
||||
@@ -123,7 +123,7 @@ public class ElasticSearchQueryManualTest {
|
||||
final NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "elasticsearch data"))
|
||||
.build();
|
||||
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(3, articles.getTotalHits());
|
||||
}
|
||||
@@ -133,14 +133,14 @@ public class ElasticSearchQueryManualTest {
|
||||
NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title.verbatim", "Second Article About Elasticsearch"))
|
||||
.build();
|
||||
|
||||
SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(1, articles.getTotalHits());
|
||||
|
||||
searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title.verbatim", "Second Article About"))
|
||||
.build();
|
||||
|
||||
articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
assertEquals(0, articles.getTotalHits());
|
||||
}
|
||||
|
||||
@@ -150,7 +150,7 @@ public class ElasticSearchQueryManualTest {
|
||||
|
||||
final NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder)
|
||||
.build();
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(2, articles.getTotalHits());
|
||||
}
|
||||
@@ -205,7 +205,7 @@ public class ElasticSearchQueryManualTest {
|
||||
final NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchPhraseQuery("title", "spring elasticsearch").slop(1))
|
||||
.build();
|
||||
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(1, articles.getTotalHits());
|
||||
}
|
||||
@@ -217,7 +217,7 @@ public class ElasticSearchQueryManualTest {
|
||||
.prefixLength(3))
|
||||
.build();
|
||||
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(1, articles.getTotalHits());
|
||||
}
|
||||
@@ -229,7 +229,7 @@ public class ElasticSearchQueryManualTest {
|
||||
.type(MultiMatchQueryBuilder.Type.BEST_FIELDS))
|
||||
.build();
|
||||
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(2, articles.getTotalHits());
|
||||
}
|
||||
@@ -241,7 +241,7 @@ public class ElasticSearchQueryManualTest {
|
||||
|
||||
final NativeSearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder)
|
||||
.build();
|
||||
final SearchHits<Article> articles = elasticsearchTemplate.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
final SearchHits<Article> articles = elasticsearchOperations.search(searchQuery, Article.class, IndexCoordinates.of("blog"));
|
||||
|
||||
assertEquals(2, articles.getTotalHits());
|
||||
}
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
package com.baeldung.spring.data.persistence.search;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
|
||||
@Entity
|
||||
public class Student {
|
||||
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
private long id;
|
||||
|
||||
private String name;
|
||||
private int score;
|
||||
|
||||
public Student() {
|
||||
}
|
||||
|
||||
public Student(String name, int score) {
|
||||
|
||||
this.name = name;
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getScore() {
|
||||
return score;
|
||||
}
|
||||
|
||||
public void setScore(int score) {
|
||||
this.score = score;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Student [id=" + id + ", name=" + name + ", score=" + score + "]";
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, name, score);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (this == obj)
|
||||
return true;
|
||||
if (obj == null)
|
||||
return false;
|
||||
if (getClass() != obj.getClass())
|
||||
return false;
|
||||
Student other = (Student) obj;
|
||||
return id == other.id && Objects.equals(name, other.name) && score == other.score;
|
||||
}
|
||||
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.baeldung.spring.data.persistence.search;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
|
||||
@SpringBootApplication
|
||||
public class StudentApplication {
|
||||
|
||||
private static final Logger log = LoggerFactory.getLogger(StudentApplication.class);
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run(StudentApplication.class, args);
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
package com.baeldung.spring.data.persistence.search;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
@Repository
|
||||
public interface StudentRepository extends JpaRepository<Student, Long> {
|
||||
|
||||
Student findFirstByOrderByScoreDesc();
|
||||
|
||||
Student findFirstBy(Sort sort);
|
||||
|
||||
Student findFirstByNameLike(String name, Sort sort);
|
||||
|
||||
List<Student> findFirst3ByOrderByScoreDesc();
|
||||
|
||||
List<Student> findFirst2ByScoreBetween(int startScore, int endScore, Sort sort);
|
||||
|
||||
Student findTopByOrderByScoreDesc();
|
||||
|
||||
Student findTopBy(Sort sort);
|
||||
|
||||
Student findTopByNameLike(String name, Sort sort);
|
||||
|
||||
List<Student> findTop3ByOrderByScoreDesc();
|
||||
|
||||
List<Student> findTop2ByScoreBetween(int startScore, int endScore, Sort sort);
|
||||
}
|
||||
@@ -3,3 +3,4 @@ spring.datasource.username=sa
|
||||
spring.datasource.password=sa
|
||||
|
||||
spring.jpa.properties.hibernate.globally_quoted_identifiers=true
|
||||
logging.level.com.baeldung.spring.data.persistence.search=debug
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
package com.baeldung.spring.data.persistence.search;
|
||||
|
||||
import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.data.domain.Sort;
|
||||
import org.springframework.test.context.junit4.SpringRunner;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest
|
||||
public class StudentApplicationUnitTest {
|
||||
|
||||
@Autowired
|
||||
private StudentRepository studentRepo;
|
||||
private List<Student> students;
|
||||
|
||||
@Before
|
||||
public void fillData() {
|
||||
students = new ArrayList<>();
|
||||
int count = 10;
|
||||
Random r = new Random();
|
||||
List<Integer> scores = r.ints(0, 101)
|
||||
.distinct()
|
||||
.limit(count)
|
||||
.boxed()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Integer score = scores.get(i);
|
||||
Student s = new Student("Student-" + i, score);
|
||||
students.add(s);
|
||||
}
|
||||
|
||||
studentRepo.saveAll(students);
|
||||
Comparator<Student> c = Comparator.comparing(a -> a.getScore());
|
||||
c = c.reversed();
|
||||
students.sort(c);
|
||||
}
|
||||
|
||||
@After
|
||||
public void clearData() {
|
||||
studentRepo.deleteAll();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStudentScores_whenMoreThanOne_thenFindFirst() {
|
||||
|
||||
Student student = studentRepo.findFirstByOrderByScoreDesc();
|
||||
Student s = students.get(0);
|
||||
assertEquals(student, s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStudentScores_whenMoreThan3_thenFindFirstThree() {
|
||||
|
||||
List<Student> firstThree = studentRepo.findFirst3ByOrderByScoreDesc();
|
||||
List<Student> sList = students.subList(0, 3);
|
||||
assertArrayEquals(firstThree.toArray(), sList.toArray());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStudentScores_whenNameMatches_thenFindFirstStudent() {
|
||||
|
||||
String matchString = "3";
|
||||
Student student = studentRepo.findFirstByNameLike("%" + matchString + "%", Sort.by("score")
|
||||
.descending());
|
||||
Student s = students.stream()
|
||||
.filter(a -> a.getName()
|
||||
.contains(matchString))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
assertEquals(student, s);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenStudentScores_whenBetweenRange_thenFindFirstTwoStudents() {
|
||||
|
||||
List<Student> topTwoBetweenRange = studentRepo.findFirst2ByScoreBetween(50, 60, Sort.by("score")
|
||||
.descending());
|
||||
List<Student> _students = students.stream()
|
||||
.filter(a -> a.getScore() >= 50 && a.getScore() <= 60)
|
||||
.limit(2)
|
||||
.collect(Collectors.toList());
|
||||
assertArrayEquals(_students.toArray(), topTwoBetweenRange.toArray());
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user