1. Overview
- Spring Data ElasticSearch simplifies native ElasticSearch
- Characteristic:
-
- Based on the @ Configuration configuration, as long as it is configured in the yml file, it can be used in the project.
-
- Tool class ElasticsearchTemplate ES template, similar to general mapper, operates ES through object
-
- Provides a Repository for the persistence layer interface, which is equivalent to using mapper
-
Comparison between elastic search and traditional database
Relational database (such as MySQL) | Non relational database (Es) |
---|---|
Database | Index Index |
Table Table | Type Type |
Row | Document |
Data Column | Field field |
Basic concepts
Technical Term | concept |
---|---|
Node (node) | A single server with elastic search service and failover and expansion. |
Cluster (cluster) | A cluster is a cluster organized by one or more node s to work together and share the whole data with load balancing function. |
Document | A document is a basic unit of information that can be indexed. |
Index (index) | Index is a collection of documents with some similar characteristics. |
Type (type) | In an index, you can define one or more types. |
Field (column) | Field is the smallest unit of Elasticsearch, which is equivalent to a column of data. |
Shards (shards) | Elastic search divides the index into several parts, each of which is a shard. |
Replicas (replication) | Replicas is an index of one or more copies. |
2. Setting up the environment
-
Create a sub module and learn elastic search
-
Step 1: modify pom.xml file and add corresponding coordinates. Add dependency for ES
<dependencies> <!--redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> </dependency> <!--test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> </dependency> <!--custom common--> <dependency> <groupId>com.czxy</groupId> <artifactId>changgou3_common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--es--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency> </dependencies>
-
Step 2: modify the yml file and add the relevant configuration of elastic search
spring: redis: database: 1 #Confirm to use the library host: 127.0.0.1 #redis service address port: 6379 #redis port number data: elasticsearch: cluster-name: elasticsearch cluster-nodes: 127.0.0.1:9300
-
Step 3: add configuration class
package com.czxy.config; import org.springframework.context.annotation.Configuration; import javax.annotation.PostConstruct; /** * @author Cloud before court * @Date 2020/4/13 20:38 * @description */ @Configuration public class ESConfig { @PostConstruct public void init(){ System.setProperty("es.set.netty.runtime.available.processors","false"); } }
3. Index operation
3.1 mapping class
-
Mapping class: used to represent the data correspondence between java and elastic search. Using annotations in spring data elastic search.
Annotated name describe @Document Used to configure the correspondence between Java class and index / type < br / > - indexname: corresponding index library name < br / > - type: corresponding type in index library < br / > - shards: partition quantity, default 5 < br / > - replicas: Replica quantity, default 1 @Id Unique identification @Field Used to configure the field correspondence between Java attributes and es < br > – type: field type, enumeration: fieldtype < br > – analyzer: participator name < br > – index: index, boolean type, default is true < br > – store: store, boolean type, default is false -
Realization
package com.czxy.vo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; 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.FieldType; /** * @author Cloud before court * @Date 2020/4/13 20:40 * @description */ @Document(indexName = "czxy56",type = "book",shards = 4,replicas = 2) @Data @NoArgsConstructor @AllArgsConstructor public class ESBook { @Id private Long id; @Field(type= FieldType.Text, analyzer = "ik_max_word") private String title;//Title @Field(type=FieldType.Keyword , index = true) private String images;//picture @Field(type=FieldType.Float) private Float price;//Price }
3.2 create index, add mapping and delete index
-
The ElasticsearchTemplate tool class provides corresponding methods to complete the following functions:
- Create index: createindex (mapping class. class)
- Add mapping: putmapping (mapping class. class)
- Delete index: deleteindex (mapping class. class)
-
1, In the test class, inject ElasticsearchTemplate
-
2, Call the corresponding API for operation
package com.czxy.elasticsearch; import com.czxy.TestApplication; import com.czxy.vo.ESBook; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.elasticsearch.core.ElasticsearchTemplate; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; /** * @author Cloud before court * @Date 2020/4/13 20:33 * @description */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestES { @Resource private ElasticsearchTemplate elasticsearchTemplate; @Test public void demo01() { //Create the index according to the @ Document annotation information of class czxy56 elasticsearchTemplate.createIndex(ESBook.class); } @Test public void demo02() { //The configuration mapping will be automatically completed according to the id, Field and other fields in the czxy56 class elasticsearchTemplate.putMapping(ESBook.class); } @Test public void demo03() { //Delete the map, which can be deleted according to the class name or index name elasticsearchTemplate.deleteIndex(ESBook.class); } }
4. Document operation (addition, deletion and modification)
4.1. Top level interface: Repository
-
Spring data elastic search provides a top-level interface Repository. You don't need to write any DAO processing, and automatically CRUD operations based on the method name or class information. As long as you define an interface and then inherit some sub interfaces provided by Repository, you can have various basic crud functions.
- PagingAndSortingRepository: (second generation) complete paging and sorting functions
- ElasticsearchCrudRepository: (the third generation) add, delete, modify and query function
- Elastic search Repository: (fourth generation) complete all functions
-
Write: just write sub interface, inherit ElasticsearchRepository, and Spring Data will load the class automatically.
- Note: when using the interface, you need to determine two generic information
- First generic: mapping class, here is ESBook
- The second generic type: the type uniquely identified by the mapping class, the type Long of the ID
package com.czxy.Repository; import com.czxy.vo.ESBook; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import java.util.List; /** * @author Cloud before court * @Date 2020/4/13 20:49 * @description */ public interface ESBookRepository extends ElasticsearchRepository<ESBook, Long> { }
4.2 add data
Method name | describe |
---|---|
save(T t) | Save a data |
saveAll( Iterable ) | Save a set of data |
package com.czxy.elasticsearch; import com.czxy.Repository.ESBookRepository; import com.czxy.TestApplication; import com.czxy.vo.ESBook; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; import java.util.ArrayList; /** * @author Cloud before court * @Date 2020/4/13 20:51 * @description */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestData { @Resource private ESBookRepository esBookRepository; @Test public void demo01() { ESBook esBook = new ESBook(1L, "Test one", "1.jpg", 998f); //Add to esBookRepository.save(esBook); } @Test public void demo02() { ArrayList<ESBook> esBooks = new ArrayList<>(); esBooks.add(new ESBook(2L, "Test two", "2.jpg", 456f)); esBooks.add(new ESBook(3L, "Test three", "3.jpg", 290f)); esBooks.add(new ESBook(4L, "Test four", "4.jpg", 100f)); //Add a set of data esBookRepository.saveAll(esBooks); } }
4.3 modify data
-
Modify and add using the same method
-
Differentiation criteria:
- If the value of id has corresponding data, update is performed.
- If the value of id does not have corresponding data, add.
@Test public void demo03() { //Update data. There must be data with id=1 in es ESBook esBook = new ESBook(1L, "Test change", "1111.jpg", 1998f); esBookRepository.save(esBook); }
4.3 delete data
@Test public void demo04() { ESBook esBook = new ESBook(); esBook.setId(1L); esBookRepository.delete(esBook); }
4.4, query
Method | describe |
---|---|
findAll() | Query all |
findById( Long ) | Query details by id |
package com.czxy.elasticsearch; import com.czxy.Repository.ESBookRepository; import com.czxy.TestApplication; import com.czxy.vo.ESBook; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; import java.util.Iterator; import java.util.List; import java.util.Optional; /** * @author Cloud before court * @Date 2020/4/13 21:01 * @description */ @RunWith(SpringRunner.class) @SpringBootTest(classes = TestApplication.class) public class TestESFind { @Resource private ESBookRepository esBookRepository; @Test public void demo01() { //Query all Iterable<ESBook> iterable = esBookRepository.findAll(); Iterator<ESBook> iterator = iterable.iterator(); while (iterator.hasNext()) { ESBook esBook = iterator.next(); System.out.println(esBook); } } @Test public void demo02() { //Query details by id Optional<ESBook> optional = esBookRepository.findById(2L); ESBook esBook = optional.get(); System.out.println(esBook); } }
- The Optional class is Java8 to solve the problem of null value judgment
- JDK8 features (self study): https://www.jianshu.com/nb/27231419
4.5 user defined method query
- Custom query: Spring Data queries automatically according to the agreed method name.
- Contract method name requirements: findBy field name | keyword, etc
- For example: findbytitle (value) queries by title
Keyword | Sample | Elasticsearch Query String |
---|---|---|
And | findByNameAndPrice | {"bool" : {"must" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}} |
Or | findByNameOrPrice | {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"price" : "?"}} ]}} |
Is | findByName | {"bool" : {"must" : {"field" : {"name" : "?"}}}} |
Not | findByNameNot | {"bool" : {"must_not" : {"field" : {"name" : "?"}}}} |
Between | findByPriceBetween | {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : ?,"include_lower" : true,"include_upper" : true}}}}} |
LessThanEqual | findByPriceLessThan | {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}} |
GreaterThanEqual | findByPriceGreaterThan | {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}} |
Before | findByPriceBefore | {"bool" : {"must" : {"range" : {"price" : {"from" : null,"to" : ?,"include_lower" : true,"include_upper" : true}}}}} |
After | findByPriceAfter | {"bool" : {"must" : {"range" : {"price" : {"from" : ?,"to" : null,"include_lower" : true,"include_upper" : true}}}}} |
Like | findByNameLike | {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}} |
StartingWith | findByNameStartingWith | {"bool" : {"must" : {"field" : {"name" : {"query" : "?*","analyze_wildcard" : true}}}}} |
EndingWith | findByNameEndingWith | {"bool" : {"must" : {"field" : {"name" : {"query" : "*?","analyze_wildcard" : true}}}}} |
Contains/Containing | findByNameContaining | {"bool" : {"must" : {"field" : {"name" : {"query" : "**?**","analyze_wildcard" : true}}}}} |
In | findByNameIn(Collection<String>names) | {"bool" : {"must" : {"bool" : {"should" : [ {"field" : {"name" : "?"}}, {"field" : {"name" : "?"}} ]}}}} |
NotIn | findByNameNotIn(Collection<String>names) | {"bool" : {"must_not" : {"bool" : {"should" : {"field" : {"name" : "?"}}}}}} |
Near | findByStoreNear | Not Supported Yet ! |
True | findByAvailableTrue | {"bool" : {"must" : {"field" : {"available" : true}}}} |
False | findByAvailableFalse | {"bool" : {"must" : {"field" : {"available" : false}}}} |
OrderBy | findByAvailableTrueOrderByNameDesc | {"sort" : [{ "name" : {"order" : "desc"} }],"bool" : {"must" : {"field" : {"available" : true}}}} |
-
Example 1: query by title
-
- Modify response custom interface and add method declaration
package com.czxy.Repository; import com.czxy.vo.ESBook; import org.springframework.data.elasticsearch.repository.ElasticsearchRepository; import java.util.List; /** * @author Cloud before court * @Date 2020/4/13 20:49 * @description */ public interface ESBookRepository extends ElasticsearchRepository<ESBook, Long> { //Example 1: query by title public List<ESBook> findByTitle(String title); }
-
- Call custom method to complete function
@Test public void demo03() { List<ESBook> list = esBookRepository.findByTitle("Test two"); System.out.println(list); }
-
-
Example 2: interval query, price 50-300
-
- statement
//Example 2: interval query, price 50-300 public List<ESBook> findByPriceBetween(Float start, Float end);
-
- call
@Test public void demo04() { List<ESBook> list = esBookRepository.findByPriceBetween(50f, 300f); System.out.println(list); }
-
-
Example 3: query price > = 290
-
- statement
//Example 3: query price > = 290 public List<ESBook> findByPriceGreaterThanEqual(Float price);
-
- call
@Test public void demo05(){ List<ESBook> list = esBookRepository.findByPriceGreaterThanEqual(290f); System.out.println(list); }
-
-
Example 4: interval query, price 50-300, and sorting by images in descending order
-
- statement
//Example 4: interval query, price 50-300, and sorted in descending order by image public List<ESBook> findByPriceBetweenOrderByImagesDesc(Float start, Float end);
-
- call
@Test public void demo06(){ List<ESBook> list = esBookRepository.findByPriceBetweenOrderByImagesDesc(50f,300f); System.out.println(list); }
-