Merge remote-tracking branch 'origin/master'
This commit is contained in:
commit
27c1ed3189
|
@ -4,7 +4,7 @@
|
|||
<classpathentry kind="src" path="src/main/java"/>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java"/>
|
||||
<classpathentry kind="src" path="src/test/resources"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
|
|
@ -3,9 +3,13 @@ package org.baeldung.spring.data.couchbase;
|
|||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.data.couchbase.config.AbstractCouchbaseConfiguration;
|
||||
import org.springframework.data.couchbase.core.mapping.event.ValidatingCouchbaseEventListener;
|
||||
import org.springframework.data.couchbase.core.query.Consistency;
|
||||
import org.springframework.data.couchbase.repository.config.EnableCouchbaseRepositories;
|
||||
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
|
||||
|
||||
@Configuration
|
||||
@EnableCouchbaseRepositories(basePackages={"org.baeldung.spring.data.couchbase"})
|
||||
|
@ -29,4 +33,19 @@ public class MyCouchbaseConfig extends AbstractCouchbaseConfiguration {
|
|||
protected String getBucketPassword() {
|
||||
return BUCKET_PASSWORD;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Consistency getDefaultConsistency() {
|
||||
return Consistency.READ_YOUR_OWN_WRITES;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public LocalValidatorFactoryBean localValidatorFactoryBean() {
|
||||
return new LocalValidatorFactoryBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ValidatingCouchbaseEventListener validatingCouchbaseEventListener() {
|
||||
return new ValidatingCouchbaseEventListener(localValidatorFactoryBean());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
package org.baeldung.spring.data.couchbase.model;
|
||||
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Past;
|
||||
import javax.validation.constraints.Pattern;
|
||||
import javax.validation.constraints.Size;
|
||||
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.annotation.Version;
|
||||
import org.springframework.data.couchbase.core.mapping.Document;
|
||||
|
||||
import com.couchbase.client.java.repository.annotation.Field;
|
||||
|
||||
@Document
|
||||
public class Student {
|
||||
private static final String NAME_REGEX = "^[a-zA-Z .'-]+$";
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
@Field
|
||||
@NotNull
|
||||
@Size(min=1, max=20)
|
||||
@Pattern(regexp=NAME_REGEX)
|
||||
private String firstName;
|
||||
@Field
|
||||
@NotNull
|
||||
@Size(min=1, max=20)
|
||||
@Pattern(regexp=NAME_REGEX)
|
||||
private String lastName;
|
||||
@Field
|
||||
@Past
|
||||
private DateTime dateOfBirth;
|
||||
@Field
|
||||
@NotNull
|
||||
private DateTime created;
|
||||
@Field
|
||||
private DateTime updated;
|
||||
@Version
|
||||
private long version;
|
||||
|
||||
public Student() {}
|
||||
|
||||
public Student(String id, String firstName, String lastName, DateTime dateOfBirth) {
|
||||
this.id = id;
|
||||
this.firstName = firstName;
|
||||
this.lastName = lastName;
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
public String getFirstName() {
|
||||
return firstName;
|
||||
}
|
||||
public void setFirstName(String firstName) {
|
||||
this.firstName = firstName;
|
||||
}
|
||||
public String getLastName() {
|
||||
return lastName;
|
||||
}
|
||||
public void setLastName(String lastName) {
|
||||
this.lastName = lastName;
|
||||
}
|
||||
public DateTime getDateOfBirth() {
|
||||
return dateOfBirth;
|
||||
}
|
||||
public void setDateOfBirth(DateTime dateOfBirth) {
|
||||
this.dateOfBirth = dateOfBirth;
|
||||
}
|
||||
public DateTime getCreated() {
|
||||
return created;
|
||||
}
|
||||
public void setCreated(DateTime created) {
|
||||
this.created = created;
|
||||
}
|
||||
public DateTime getUpdated() {
|
||||
return updated;
|
||||
}
|
||||
public void setUpdated(DateTime updated) {
|
||||
this.updated = updated;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int hash = 1;
|
||||
if(id != null) {
|
||||
hash = hash * 31 + id.hashCode();
|
||||
}
|
||||
if(firstName != null) {
|
||||
hash = hash * 31 + firstName.hashCode();
|
||||
}
|
||||
if(lastName != null) {
|
||||
hash = hash * 31 + lastName.hashCode();
|
||||
}
|
||||
if(dateOfBirth != null) {
|
||||
hash = hash * 31 + dateOfBirth.hashCode();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if((obj == null) || (obj.getClass() != this.getClass())) return false;
|
||||
if(obj == this) return true;
|
||||
Student other = (Student) obj;
|
||||
return this.hashCode() == other.hashCode();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package org.baeldung.spring.data.couchbase.repos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.baeldung.spring.data.couchbase.model.Student;
|
||||
|
||||
public interface CustomStudentRepository {
|
||||
List<Student> findByFirstNameStartsWith(String s);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
package org.baeldung.spring.data.couchbase.repos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.baeldung.spring.data.couchbase.model.Student;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
|
||||
import com.couchbase.client.java.view.Stale;
|
||||
import com.couchbase.client.java.view.ViewQuery;
|
||||
|
||||
public class CustomStudentRepositoryImpl implements CustomStudentRepository {
|
||||
|
||||
private static final String DESIGN_DOC = "student";
|
||||
|
||||
@Autowired
|
||||
private CouchbaseTemplate template;
|
||||
|
||||
public List<Student> findByFirstNameStartsWith(String s) {
|
||||
return template.findByView(ViewQuery.from(DESIGN_DOC, "byFirstName")
|
||||
.startKey(s)
|
||||
.stale(Stale.FALSE),
|
||||
Student.class);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
package org.baeldung.spring.data.couchbase.repos;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.baeldung.spring.data.couchbase.model.Student;
|
||||
import org.springframework.data.repository.CrudRepository;
|
||||
|
||||
public interface StudentRepository extends CrudRepository<Student, String>, CustomStudentRepository {
|
||||
List<Student> findByFirstName(String firstName);
|
||||
List<Student> findByLastName(String lastName);
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package org.baeldung.spring.data.couchbase.service;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.baeldung.spring.data.couchbase.model.Student;
|
||||
import org.baeldung.spring.data.couchbase.repos.StudentRepository;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@Qualifier("StudentRepositoryService")
|
||||
public class StudentRepositoryService implements StudentService {
|
||||
|
||||
private StudentRepository repo;
|
||||
@Autowired
|
||||
public void setStudentRepository(StudentRepository repo) {
|
||||
this.repo = repo;
|
||||
}
|
||||
|
||||
public Student findOne(String id) {
|
||||
return repo.findOne(id);
|
||||
}
|
||||
|
||||
public List<Student> findAll() {
|
||||
List<Student> people = new ArrayList<Student>();
|
||||
Iterator<Student> it = repo.findAll().iterator();
|
||||
while(it.hasNext()) {
|
||||
people.add(it.next());
|
||||
}
|
||||
return people;
|
||||
}
|
||||
|
||||
public List<Student> findByFirstName(String firstName) {
|
||||
return repo.findByFirstName(firstName);
|
||||
}
|
||||
|
||||
public List<Student> findByLastName(String lastName) {
|
||||
return repo.findByLastName(lastName);
|
||||
}
|
||||
|
||||
public void create(Student student) {
|
||||
student.setCreated(DateTime.now());
|
||||
repo.save(student);
|
||||
}
|
||||
|
||||
public void update(Student student) {
|
||||
student.setUpdated(DateTime.now());
|
||||
repo.save(student);
|
||||
}
|
||||
|
||||
public void delete(Student student) {
|
||||
repo.delete(student);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
package org.baeldung.spring.data.couchbase.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.baeldung.spring.data.couchbase.model.Student;
|
||||
|
||||
public interface StudentService {
|
||||
|
||||
Student findOne(String id);
|
||||
|
||||
List<Student> findAll();
|
||||
|
||||
List<Student> findByFirstName(String firstName);
|
||||
|
||||
List<Student> findByLastName(String lastName);
|
||||
|
||||
void create(Student student);
|
||||
|
||||
void update(Student student);
|
||||
|
||||
void delete(Student student);
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package org.baeldung.spring.data.couchbase.service;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.baeldung.spring.data.couchbase.model.Student;
|
||||
import org.joda.time.DateTime;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.couchbase.core.CouchbaseTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import com.couchbase.client.java.view.ViewQuery;
|
||||
|
||||
@Service
|
||||
@Qualifier("StudentTemplateService")
|
||||
public class StudentTemplateService implements StudentService {
|
||||
|
||||
private static final String DESIGN_DOC = "student";
|
||||
|
||||
private CouchbaseTemplate template;
|
||||
@Autowired
|
||||
public void setCouchbaseTemplate(CouchbaseTemplate template) {
|
||||
this.template = template;
|
||||
}
|
||||
|
||||
public Student findOne(String id) {
|
||||
return template.findById(id, Student.class);
|
||||
}
|
||||
|
||||
public List<Student> findAll() {
|
||||
return template.findByView(ViewQuery.from(DESIGN_DOC, "all"), Student.class);
|
||||
}
|
||||
|
||||
public List<Student> findByFirstName(String firstName) {
|
||||
return template.findByView(ViewQuery.from(DESIGN_DOC, "byFirstName"), Student.class);
|
||||
}
|
||||
|
||||
public List<Student> findByLastName(String lastName) {
|
||||
return template.findByView(ViewQuery.from(DESIGN_DOC, "byLastName"), Student.class);
|
||||
}
|
||||
|
||||
public void create(Student student) {
|
||||
student.setCreated(DateTime.now());
|
||||
template.insert(student);
|
||||
}
|
||||
|
||||
public void update(Student student) {
|
||||
student.setUpdated(DateTime.now());
|
||||
template.update(student);
|
||||
}
|
||||
|
||||
public void delete(Student student) {
|
||||
template.remove(student);
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package org.baeldung.spring.data.couchbase;
|
||||
|
||||
import org.springframework.data.couchbase.core.convert.MappingCouchbaseConverter;
|
||||
import org.springframework.data.couchbase.core.query.Consistency;
|
||||
|
||||
public class TestCouchbaseConfig extends MyCouchbaseConfig {
|
||||
|
||||
|
@ -8,4 +9,9 @@ public class TestCouchbaseConfig extends MyCouchbaseConfig {
|
|||
public String typeKey() {
|
||||
return MappingCouchbaseConverter.TYPEKEY_SYNCGATEWAY_COMPATIBLE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Consistency getDefaultConsistency() {
|
||||
return Consistency.READ_YOUR_OWN_WRITES;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package org.baeldung.spring.data.couchbase.service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
public class StudentRepositoryServiceTest extends StudentServiceTest {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("StudentRepositoryService")
|
||||
public void setStudentService(StudentService service) {
|
||||
this.studentService = service;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,166 @@
|
|||
package org.baeldung.spring.data.couchbase.service;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.validation.ConstraintViolationException;
|
||||
|
||||
import org.baeldung.spring.data.couchbase.IntegrationTest;
|
||||
import org.baeldung.spring.data.couchbase.MyCouchbaseConfig;
|
||||
import org.baeldung.spring.data.couchbase.model.Student;
|
||||
import org.joda.time.DateTime;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.couchbase.client.java.Bucket;
|
||||
import com.couchbase.client.java.Cluster;
|
||||
import com.couchbase.client.java.CouchbaseCluster;
|
||||
import com.couchbase.client.java.document.JsonDocument;
|
||||
import com.couchbase.client.java.document.json.JsonObject;
|
||||
|
||||
public abstract class StudentServiceTest extends IntegrationTest {
|
||||
|
||||
static final String typeField = "_class";
|
||||
static final String joe = "Joe";
|
||||
static final String college = "College";
|
||||
static final String joeCollegeId = "student:" + joe + ":" + college;
|
||||
static final DateTime joeCollegeDob = DateTime.now().minusYears(21);
|
||||
static final Student joeCollege = new Student(joeCollegeId, joe, college, joeCollegeDob);
|
||||
static final JsonObject jsonJoeCollege = JsonObject.empty()
|
||||
.put(typeField, Student.class.getName())
|
||||
.put("firstName", joe)
|
||||
.put("lastName", college)
|
||||
.put("created", DateTime.now().getMillis())
|
||||
.put("version", 1);
|
||||
|
||||
static final String judy = "Judy";
|
||||
static final String jetson = "Jetson";
|
||||
static final String judyJetsonId = "student:" + judy + ":" + jetson;
|
||||
static final DateTime judyJetsonDob = DateTime.now().minusYears(19).minusMonths(5).minusDays(3);
|
||||
static final Student judyJetson = new Student(judyJetsonId, judy, jetson, judyJetsonDob);
|
||||
static final JsonObject jsonJudyJetson = JsonObject.empty()
|
||||
.put(typeField, Student.class.getName())
|
||||
.put("firstName", judy)
|
||||
.put("lastName", jetson)
|
||||
.put("created", DateTime.now().getMillis())
|
||||
.put("version", 1);
|
||||
|
||||
StudentService studentService;
|
||||
|
||||
@BeforeClass
|
||||
public static void setupBeforeClass() {
|
||||
Cluster cluster = CouchbaseCluster.create(MyCouchbaseConfig.NODE_LIST);
|
||||
Bucket bucket = cluster.openBucket(MyCouchbaseConfig.BUCKET_NAME, MyCouchbaseConfig.BUCKET_PASSWORD);
|
||||
bucket.upsert(JsonDocument.create(joeCollegeId, jsonJoeCollege));
|
||||
bucket.upsert(JsonDocument.create(judyJetsonId, jsonJudyJetson));
|
||||
bucket.close();
|
||||
cluster.disconnect();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenCreatingStudent_thenDocumentIsPersisted() {
|
||||
String firstName = "Eric";
|
||||
String lastName = "Stratton";
|
||||
DateTime dateOfBirth = DateTime.now().minusYears(25);
|
||||
String id = "student:" + firstName + ":" + lastName;
|
||||
Student expectedStudent = new Student(id, firstName, lastName, dateOfBirth);
|
||||
studentService.create(expectedStudent);
|
||||
Student actualStudent = studentService.findOne(id);
|
||||
assertNotNull(actualStudent.getCreated());
|
||||
assertNotNull(actualStudent);
|
||||
assertEquals(expectedStudent.getId(), actualStudent.getId());
|
||||
}
|
||||
|
||||
@Test(expected=ConstraintViolationException.class)
|
||||
public void whenCreatingStudentWithInvalidFirstName_thenConstraintViolationException() {
|
||||
String firstName = "Er+ic";
|
||||
String lastName = "Stratton";
|
||||
DateTime dateOfBirth = DateTime.now().minusYears(25);
|
||||
String id = "student:" + firstName + ":" + lastName;
|
||||
Student student = new Student(id, firstName, lastName, dateOfBirth);
|
||||
studentService.create(student);
|
||||
}
|
||||
|
||||
@Test(expected=ConstraintViolationException.class)
|
||||
public void whenCreatingStudentWithFutureDob_thenConstraintViolationException() {
|
||||
String firstName = "Jane";
|
||||
String lastName = "Doe";
|
||||
DateTime dateOfBirth = DateTime.now().plusDays(1);
|
||||
String id = "student:" + firstName + ":" + lastName;
|
||||
Student student = new Student(id, firstName, lastName, dateOfBirth);
|
||||
studentService.create(student);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFindingStudentByJohnSmithId_thenReturnsJohnSmith() {
|
||||
Student actualStudent = studentService.findOne(joeCollegeId);
|
||||
assertNotNull(actualStudent);
|
||||
assertNotNull(actualStudent.getCreated());
|
||||
assertEquals(joeCollegeId, actualStudent.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFindingAllStudents_thenReturnsTwoOrMoreStudentsIncludingJoeCollegeAndJudyJetson() {
|
||||
List<Student> resultList = studentService.findAll();
|
||||
assertNotNull(resultList);
|
||||
assertFalse(resultList.isEmpty());
|
||||
assertTrue(resultContains(resultList, joeCollege));
|
||||
assertTrue(resultContains(resultList, judyJetson));
|
||||
assertTrue(resultList.size() >= 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFindingByFirstNameJohn_thenReturnsOnlyStudentsNamedJohn() {
|
||||
String expectedFirstName = joe;
|
||||
List<Student> resultList = studentService.findByFirstName(expectedFirstName);
|
||||
assertNotNull(resultList);
|
||||
assertFalse(resultList.isEmpty());
|
||||
assertTrue(allResultsContainExpectedFirstName(resultList, expectedFirstName));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void whenFindingByLastNameSmith_thenReturnsOnlyStudentsNamedSmith() {
|
||||
String expectedLastName = college;
|
||||
List<Student> resultList = studentService.findByLastName(expectedLastName);
|
||||
assertNotNull(resultList);
|
||||
assertFalse(resultList.isEmpty());
|
||||
assertTrue(allResultsContainExpectedLastName(resultList, expectedLastName));
|
||||
}
|
||||
|
||||
private boolean resultContains(List<Student> resultList, Student student) {
|
||||
boolean found = false;
|
||||
for(Student p : resultList) {
|
||||
if(p.getId().equals(student.getId())) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean allResultsContainExpectedFirstName(List<Student> resultList, String firstName) {
|
||||
boolean found = false;
|
||||
for(Student p : resultList) {
|
||||
if(p.getFirstName().equals(firstName)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
private boolean allResultsContainExpectedLastName(List<Student> resultList, String lastName) {
|
||||
boolean found = false;
|
||||
for(Student p : resultList) {
|
||||
if(p.getLastName().equals(lastName)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return found;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package org.baeldung.spring.data.couchbase.service;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
|
||||
public class StudentTemplateServiceTest extends StudentServiceTest {
|
||||
|
||||
@Autowired
|
||||
@Qualifier("StudentTemplateService")
|
||||
public void setStudentService(StudentService service) {
|
||||
this.studentService = service;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" output="target/classes" path="src/main/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
|
||||
<attributes>
|
||||
<attribute name="optional" value="true"/>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="maven.pomderived" value="true"/>
|
||||
</attributes>
|
||||
</classpathentry>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>spring-data-elasticsearch</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.m2e.core.maven2Builder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
<buildCommand>
|
||||
<name>org.springframework.ide.eclipse.core.springbuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.springframework.ide.eclipse.core.springnature</nature>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
<nature>org.eclipse.m2e.core.maven2Nature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
|
@ -18,7 +18,7 @@
|
|||
<junit.version>4.11</junit.version>
|
||||
<org.slf4j.version>1.7.12</org.slf4j.version>
|
||||
<logback.version>1.1.3</logback.version>
|
||||
<elasticsearch.version>1.3.2.RELEASE</elasticsearch.version>
|
||||
<elasticsearch.version>2.0.1.RELEASE</elasticsearch.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
|
@ -44,6 +44,11 @@
|
|||
<artifactId>spring-data-elasticsearch</artifactId>
|
||||
<version>${elasticsearch.version}</version>
|
||||
</dependency>
|
||||
<dependency> <groupId>net.java.dev.jna</groupId>
|
||||
<artifactId>jna</artifactId>
|
||||
<version>4.1.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
package com.baeldung.spring.data.es.config;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.settings.ImmutableSettings;
|
||||
import org.elasticsearch.common.settings.Settings;
|
||||
import org.elasticsearch.node.NodeBuilder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.ComponentScan;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
@ -12,35 +18,33 @@ import org.springframework.data.elasticsearch.core.ElasticsearchOperations;
|
|||
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
|
||||
import org.springframework.data.elasticsearch.repository.config.EnableElasticsearchRepositories;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
|
||||
@Configuration
|
||||
@EnableElasticsearchRepositories(basePackages = "com.baeldung.spring.data.es.repository")
|
||||
@ComponentScan(basePackages = {"com.baeldung.spring.data.es.service"})
|
||||
@ComponentScan(basePackages = { "com.baeldung.spring.data.es.service" })
|
||||
public class Config {
|
||||
|
||||
@Value("${elasticsearch.home:/usr/local/Cellar/elasticsearch/2.3.2}")
|
||||
private String elasticsearchHome;
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(Config.class);
|
||||
|
||||
@Bean
|
||||
public Client client() {
|
||||
try {
|
||||
Path tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")), "elasticsearch_data");
|
||||
final Path tmpDir = Files.createTempDirectory(Paths.get(System.getProperty("java.io.tmpdir")), "elasticsearch_data");
|
||||
|
||||
ImmutableSettings.Builder elasticsearchSettings = ImmutableSettings.settingsBuilder()
|
||||
.put("http.enabled", "false")
|
||||
.put("path.data", tmpDir.toAbsolutePath().toString());
|
||||
// @formatter:off
|
||||
|
||||
final Settings.Builder elasticsearchSettings =
|
||||
Settings.settingsBuilder().put("http.enabled", "false")
|
||||
.put("path.data", tmpDir.toAbsolutePath().toString())
|
||||
.put("path.home", elasticsearchHome);
|
||||
// @formatter:on
|
||||
|
||||
logger.debug(tmpDir.toAbsolutePath().toString());
|
||||
|
||||
return new NodeBuilder()
|
||||
.local(true)
|
||||
.settings(elasticsearchSettings.build())
|
||||
.node()
|
||||
.client();
|
||||
} catch (IOException ioex) {
|
||||
return new NodeBuilder().local(true).settings(elasticsearchSettings.build()).node().client();
|
||||
} catch (final IOException ioex) {
|
||||
logger.error("Cannot create temp dir", ioex);
|
||||
throw new RuntimeException();
|
||||
}
|
||||
|
|
|
@ -1,27 +1,25 @@
|
|||
package com.baeldung.spring.data.es.model;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.*;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldIndex.not_analyzed;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.Nested;
|
||||
import static org.springframework.data.elasticsearch.annotations.FieldType.String;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.data.annotation.Id;
|
||||
import org.springframework.data.elasticsearch.annotations.Document;
|
||||
import org.springframework.data.elasticsearch.annotations.Field;
|
||||
import org.springframework.data.elasticsearch.annotations.InnerField;
|
||||
import org.springframework.data.elasticsearch.annotations.MultiField;
|
||||
|
||||
@Document(indexName = "blog", type = "article")
|
||||
public class Article {
|
||||
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
@MultiField(
|
||||
mainField = @Field(type = String),
|
||||
otherFields = {
|
||||
@NestedField(index = not_analyzed, dotSuffix = "verbatim", type = String)
|
||||
}
|
||||
)
|
||||
@MultiField(mainField = @Field(type = String), otherFields = { @InnerField(index = not_analyzed, suffix = "verbatim", type = String) })
|
||||
private String title;
|
||||
|
||||
@Field(type = Nested)
|
||||
|
@ -71,11 +69,6 @@ public class Article {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Article{" +
|
||||
"id='" + id + '\'' +
|
||||
", title='" + title + '\'' +
|
||||
", authors=" + authors +
|
||||
", tags=" + Arrays.toString(tags) +
|
||||
'}';
|
||||
return "Article{" + "id='" + id + '\'' + ", title='" + title + '\'' + ", authors=" + authors + ", tags=" + Arrays.toString(tags) + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,8 +21,6 @@ public class Author {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Author{" +
|
||||
"name='" + name + '\'' +
|
||||
'}';
|
||||
return "Author{" + "name='" + name + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,10 +6,16 @@ import org.springframework.data.domain.Pageable;
|
|||
|
||||
public interface ArticleService {
|
||||
Article save(Article article);
|
||||
|
||||
Article findOne(String id);
|
||||
|
||||
Iterable<Article> findAll();
|
||||
|
||||
Page<Article> findByAuthorName(String name, Pageable pageable);
|
||||
|
||||
Page<Article> findByAuthorNameUsingCustomQuery(String name, Pageable pageable);
|
||||
|
||||
long count();
|
||||
|
||||
void delete(Article article);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,6 @@ public class ArticleServiceImpl implements ArticleService {
|
|||
|
||||
@Override
|
||||
public void delete(Article article) {
|
||||
articleRepository.delete(article);
|
||||
articleRepository.delete(article);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,20 @@
|
|||
package com.baeldung.spring.data.es;
|
||||
|
||||
import com.baeldung.spring.data.es.config.Config;
|
||||
import com.baeldung.spring.data.es.model.Article;
|
||||
import com.baeldung.spring.data.es.model.Author;
|
||||
import com.baeldung.spring.data.es.service.ArticleService;
|
||||
import org.elasticsearch.action.ActionFuture;
|
||||
import org.elasticsearch.action.index.IndexRequest;
|
||||
import org.elasticsearch.action.index.IndexResponse;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.boolQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchPhraseQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.multiMatchQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.nestedQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.termQuery;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.elasticsearch.action.search.SearchResponse;
|
||||
import org.elasticsearch.client.Client;
|
||||
import org.elasticsearch.common.unit.Fuzziness;
|
||||
|
@ -28,19 +36,13 @@ import org.springframework.test.context.ContextConfiguration;
|
|||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.stream.Collectors.toList;
|
||||
import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import com.baeldung.spring.data.es.config.Config;
|
||||
import com.baeldung.spring.data.es.model.Article;
|
||||
import com.baeldung.spring.data.es.model.Author;
|
||||
import com.baeldung.spring.data.es.service.ArticleService;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {Config.class}, loader = AnnotationConfigContextLoader.class)
|
||||
@ContextConfiguration(classes = { Config.class }, loader = AnnotationConfigContextLoader.class)
|
||||
public class ElasticSearchQueryTest {
|
||||
|
||||
@Autowired
|
||||
|
@ -60,7 +62,7 @@ public class ElasticSearchQueryTest {
|
|||
elasticsearchTemplate.deleteIndex(Article.class);
|
||||
elasticsearchTemplate.createIndex(Article.class);
|
||||
elasticsearchTemplate.putMapping(Article.class);
|
||||
elasticsearchTemplate.refresh(Article.class, true);
|
||||
elasticsearchTemplate.refresh(Article.class);
|
||||
|
||||
Article article = new Article("Spring Data Elasticsearch");
|
||||
article.setAuthors(asList(johnSmith, johnDoe));
|
||||
|
@ -85,127 +87,92 @@ public class ElasticSearchQueryTest {
|
|||
|
||||
@Test
|
||||
public void givenFullTitle_whenRunMatchQuery_thenDocIsFound() {
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchQuery("title", "Search engines").operator(AND))
|
||||
.build();
|
||||
List<Article> articles = elasticsearchTemplate
|
||||
.queryForList(searchQuery, Article.class);
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Search engines").operator(AND)).build();
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(1, articles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenOneTermFromTitle_whenRunMatchQuery_thenDocIsFound() {
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchQuery("title", "Engines Solutions"))
|
||||
.build();
|
||||
List<Article> articles = elasticsearchTemplate
|
||||
.queryForList(searchQuery, Article.class);
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Engines Solutions")).build();
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(1, articles.size());
|
||||
assertEquals("Search engines", articles.get(0).getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPartTitle_whenRunMatchQuery_thenDocIsFound() {
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchQuery("title", "elasticsearch data"))
|
||||
.build();
|
||||
List<Article> articles = elasticsearchTemplate
|
||||
.queryForList(searchQuery, Article.class);
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "elasticsearch data")).build();
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(3, articles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenFullTitle_whenRunMatchQueryOnVerbatimField_thenDocIsFound() {
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchQuery("title.verbatim", "Second Article About Elasticsearch"))
|
||||
.build();
|
||||
List<Article> articles = elasticsearchTemplate
|
||||
.queryForList(searchQuery, Article.class);
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title.verbatim", "Second Article About Elasticsearch")).build();
|
||||
List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(1, articles.size());
|
||||
|
||||
searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchQuery("title.verbatim", "Second Article About"))
|
||||
.build();
|
||||
articles = elasticsearchTemplate
|
||||
.queryForList(searchQuery, Article.class);
|
||||
searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title.verbatim", "Second Article About")).build();
|
||||
articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(0, articles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNestedObject_whenQueryByAuthorsName_thenFoundArticlesByThatAuthor() {
|
||||
QueryBuilder builder = nestedQuery("authors",
|
||||
boolQuery().must(termQuery("authors.name", "smith")));
|
||||
final QueryBuilder builder = nestedQuery("authors", boolQuery().must(termQuery("authors.name", "smith")));
|
||||
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
|
||||
List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).build();
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
|
||||
assertEquals(2, articles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenAnalyzedQuery_whenMakeAggregationOnTermCount_thenEachTokenCountsSeparately() {
|
||||
TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("title");
|
||||
SearchResponse response = client.prepareSearch("blog").setTypes("article")
|
||||
.addAggregation(aggregation).execute().actionGet();
|
||||
final TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("title");
|
||||
final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation).execute().actionGet();
|
||||
|
||||
Map<String, Aggregation> results = response.getAggregations().asMap();
|
||||
StringTerms topTags = (StringTerms) results.get("top_tags");
|
||||
final Map<String, Aggregation> results = response.getAggregations().asMap();
|
||||
final StringTerms topTags = (StringTerms) results.get("top_tags");
|
||||
|
||||
List<String> keys = topTags.getBuckets().stream().map(b -> b.getKey()).collect(toList());
|
||||
final List<String> keys = topTags.getBuckets().stream().map(b -> b.getKeyAsString()).collect(toList());
|
||||
Collections.sort(keys);
|
||||
assertEquals(asList("about", "article", "data", "elasticsearch",
|
||||
"engines", "search", "second", "spring", "tutorial"), keys);
|
||||
assertEquals(asList("about", "article", "data", "elasticsearch", "engines", "search", "second", "spring", "tutorial"), keys);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNotAnalyzedQuery_whenMakeAggregationOnTermCount_thenEachTermCountsIndividually() {
|
||||
TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("tags")
|
||||
.order(Terms.Order.aggregation("_count", false));
|
||||
SearchResponse response = client.prepareSearch("blog").setTypes("article")
|
||||
.addAggregation(aggregation).execute().actionGet();
|
||||
final TermsBuilder aggregation = AggregationBuilders.terms("top_tags").field("tags").order(Terms.Order.aggregation("_count", false));
|
||||
final SearchResponse response = client.prepareSearch("blog").setTypes("article").addAggregation(aggregation).execute().actionGet();
|
||||
|
||||
Map<String, Aggregation> results = response.getAggregations().asMap();
|
||||
StringTerms topTags = (StringTerms) results.get("top_tags");
|
||||
final Map<String, Aggregation> results = response.getAggregations().asMap();
|
||||
final StringTerms topTags = (StringTerms) results.get("top_tags");
|
||||
|
||||
List<String> keys = topTags.getBuckets().stream().map(b -> b.getKey()).collect(toList());
|
||||
final List<String> keys = topTags.getBuckets().stream().map(b -> b.getKeyAsString()).collect(toList());
|
||||
assertEquals(asList("elasticsearch", "spring data", "search engines", "tutorial"), keys);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenNotExactPhrase_whenUseSlop_thenQueryMatches() {
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchPhraseQuery("title", "spring elasticsearch").slop(1))
|
||||
.build();
|
||||
List<Article> articles = elasticsearchTemplate
|
||||
.queryForList(searchQuery, Article.class);
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchPhraseQuery("title", "spring elasticsearch").slop(1)).build();
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(1, articles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenPhraseWithType_whenUseFuzziness_thenQueryMatches() {
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchQuery("title", "spring date elasticserch")
|
||||
.operator(AND)
|
||||
.fuzziness(Fuzziness.ONE)
|
||||
.prefixLength(3))
|
||||
.build();
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "spring date elasticserch").operator(AND).fuzziness(Fuzziness.ONE).prefixLength(3)).build();
|
||||
|
||||
List<Article> articles = elasticsearchTemplate
|
||||
.queryForList(searchQuery, Article.class);
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(1, articles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenMultimatchQuery_whenDoSearch_thenAllProvidedFieldsMatch() {
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(multiMatchQuery("tutorial")
|
||||
.field("title")
|
||||
.field("tags")
|
||||
.type(MultiMatchQueryBuilder.Type.BEST_FIELDS))
|
||||
.build();
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(multiMatchQuery("tutorial").field("title").field("tags").type(MultiMatchQueryBuilder.Type.BEST_FIELDS)).build();
|
||||
|
||||
List<Article> articles = elasticsearchTemplate
|
||||
.queryForList(searchQuery, Article.class);
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(2, articles.size());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
package com.baeldung.spring.data.es;
|
||||
|
||||
import com.baeldung.spring.data.es.config.Config;
|
||||
import com.baeldung.spring.data.es.model.Article;
|
||||
import com.baeldung.spring.data.es.model.Author;
|
||||
import com.baeldung.spring.data.es.service.ArticleService;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.fuzzyQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.matchQuery;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.regexpQuery;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
@ -17,17 +23,13 @@ import org.springframework.test.context.ContextConfiguration;
|
|||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.support.AnnotationConfigContextLoader;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.elasticsearch.index.query.FilterBuilders.regexpFilter;
|
||||
import static org.elasticsearch.index.query.MatchQueryBuilder.Operator.AND;
|
||||
import static org.elasticsearch.index.query.QueryBuilders.*;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import com.baeldung.spring.data.es.config.Config;
|
||||
import com.baeldung.spring.data.es.model.Article;
|
||||
import com.baeldung.spring.data.es.model.Author;
|
||||
import com.baeldung.spring.data.es.service.ArticleService;
|
||||
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = {Config.class}, loader = AnnotationConfigContextLoader.class)
|
||||
@ContextConfiguration(classes = { Config.class }, loader = AnnotationConfigContextLoader.class)
|
||||
public class ElasticSearchTest {
|
||||
|
||||
@Autowired
|
||||
|
@ -59,8 +61,7 @@ public class ElasticSearchTest {
|
|||
|
||||
@Test
|
||||
public void givenArticleService_whenSaveArticle_thenIdIsAssigned() {
|
||||
List<Author> authors = asList(
|
||||
new Author("John Smith"), johnDoe);
|
||||
final List<Author> authors = asList(new Author("John Smith"), johnDoe);
|
||||
|
||||
Article article = new Article("Making Search Elastic");
|
||||
article.setAuthors(authors);
|
||||
|
@ -72,39 +73,34 @@ public class ElasticSearchTest {
|
|||
@Test
|
||||
public void givenPersistedArticles_whenSearchByAuthorsName_thenRightFound() {
|
||||
|
||||
Page<Article> articleByAuthorName = articleService.findByAuthorName(johnSmith.getName(), new PageRequest(0, 10));
|
||||
final Page<Article> articleByAuthorName = articleService.findByAuthorName(johnSmith.getName(), new PageRequest(0, 10));
|
||||
assertEquals(2L, articleByAuthorName.getTotalElements());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenCustomQuery_whenSearchByAuthorsName_thenArticleIsFound() {
|
||||
|
||||
Page<Article> articleByAuthorName = articleService.findByAuthorNameUsingCustomQuery("John Smith", new PageRequest(0, 10));
|
||||
final Page<Article> articleByAuthorName = articleService.findByAuthorNameUsingCustomQuery("John Smith", new PageRequest(0, 10));
|
||||
assertEquals(3L, articleByAuthorName.getTotalElements());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
public void givenPersistedArticles_whenUseRegexQuery_thenRightArticlesFound() {
|
||||
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withFilter(regexpFilter("title", ".*data.*"))
|
||||
.build();
|
||||
List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withFilter(regexpQuery("title", ".*data.*")).build();
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
|
||||
assertEquals(1, articles.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void givenSavedDoc_whenTitleUpdated_thenCouldFindByUpdatedTitle() {
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(fuzzyQuery("title", "serch"))
|
||||
.build();
|
||||
List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(fuzzyQuery("title", "serch")).build();
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
|
||||
assertEquals(1, articles.size());
|
||||
|
||||
Article article = articles.get(0);
|
||||
final Article article = articles.get(0);
|
||||
final String newTitle = "Getting started with Search Engines";
|
||||
article.setTitle(newTitle);
|
||||
articleService.save(article);
|
||||
|
@ -117,10 +113,8 @@ public class ElasticSearchTest {
|
|||
|
||||
final String articleTitle = "Spring Data Elasticsearch";
|
||||
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchQuery("title", articleTitle).minimumShouldMatch("75%"))
|
||||
.build();
|
||||
List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", articleTitle).minimumShouldMatch("75%")).build();
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(1, articles.size());
|
||||
final long count = articleService.count();
|
||||
|
||||
|
@ -131,10 +125,8 @@ public class ElasticSearchTest {
|
|||
|
||||
@Test
|
||||
public void givenSavedDoc_whenOneTermMatches_thenFindByTitle() {
|
||||
SearchQuery searchQuery = new NativeSearchQueryBuilder()
|
||||
.withQuery(matchQuery("title", "Search engines").operator(AND))
|
||||
.build();
|
||||
List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
final SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(matchQuery("title", "Search engines").operator(AND)).build();
|
||||
final List<Article> articles = elasticsearchTemplate.queryForList(searchQuery, Article.class);
|
||||
assertEquals(1, articles.size());
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue