Table of contents
Spring Data ElasticSearch query method
Spring Data Solr Common Recipes
4 Spring Data ElasticSearch query method
4.1 Manipulate documents using methods inherited from Repository
ElasticsearchTemplate is mainly responsible for operating the index library. We can use methods inherited from Repository to operate on documents
4.2 Naming rule query document
The naming rules of es are basically the same as those of jpa, and the common ones are as follows:
4.3 Query documents using native methods
ES itself supports some special queries, such as fuzzy query, word segmentation before querying, etc. We can use @Query annotation to customize query conditions on interface methods. like:
@Query("{\n" +
" \"fuzzy\": {\n" +
" \"productName\": {\n" +
" \"value\":\"elasticsearch\",\n" +
" \"max_expansions\":1\n" +
" }\n" +
" }\n" +
"}")
List<Product> findByProductNameFuzzy(String productName);
@Query("{\n" +
" \"query_string\": {\n" +
" \"query\": \"?0\",\n" +
" \"default_field\": \"productName\"\n" +
" }\n" +
"}")
List<Product> findByProductNameString(String productName);
4.4 Pagination query
When using the custom or inherited methods of the repository, add Pageable parameters to the parameters, and the return value is Page type to complete the pagination query.
4.5 Using Template to operate ElasticSearch
SpringDataElasticsearch also supports Template mode operation, we need to inject an ElasticsearchRestTemplate object into the class.
4.5.1 Operation index
(1) The template calls IndexOperations indexOps(Class clazz) to obtain the index operation object.
(2) Common methods of IndexOperations:
create(): Create an index. Note: This method cannot set the index structure, and there are bugs left in the framework
delete(): delete the index
4.5.2 Add, delete and modify documents
Common methods for template manipulation documents:
save(): add/modify documents
delete(): delete the document
4.5.3 Querying documents
The search method of the template can query documents:
SearchHits search(Query query, Class clazz): query documents, query is the query condition object, clazz is the result type.
1. Common query: build Query object
// 构建查询条件
// 单词查询
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("productDesc", "科幻");
// 模糊查询
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("productName", "三体
").maxExpansions(2);
// 先分词后查询
QueryStringQueryBuilder queryStringQueryBuilder = QueryBuilders.queryStringQuery("我喜欢三
体").defaultField("productName");
// 构建 Query 对象
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(termQueryBuilder).build();
Query and process the results:
// 查询
SearchHits<Product> search = template.search(query, Product.class);
System.out.println(search.getMaxScore());
System.out.println(search.getTotalHits());
for (SearchHit<Product> productSearchHit : search) {
System.out.println(productSearchHit.getContent());
}
2. Query with complex conditions
String productName = "三";
String productDesc = null;
// 构建查询条件
BoolQueryBuilder defaultQueryBuilder = QueryBuilders.boolQuery();
if(productName != null){
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("productName", productName);
defaultQueryBuilder.should(termQueryBuilder);
}
if(productDesc != null){
FuzzyQueryBuilder fuzzyQueryBuilder = QueryBuilders.fuzzyQuery("productDesc", productDesc).maxExpansions(2);
defaultQueryBuilder.should(fuzzyQueryBuilder);
}
// 构建 Query 对象
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(defaultQueryBuilder).build();
3. Paging query
// 构建 Query 对象
Pageable pageable = PageRequest.of(0,5);
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(defaultQueryBuilder)
.withPageable(pageable)
.build();
// 查询
SearchHits<Product> search = template.search(query, Product.class);
// 封装页面对象
Page<Product> page = new PageImpl(search.toList(),pageable,search.getTotalHits());
System.out.println(page.getTotalElements());
System.out.println(page.getTotalPages());
System.out.println(page.getContent());
4. Sort query
SortBuilder sortBuilder = SortBuilders.fieldSort("id").order(SortOrder.DESC);
NativeSearchQuery query = new NativeSearchQueryBuilder()
.withQuery(defaultQueryBuilder)
.withSort(sortBuilder)
.build();
六、 Spring Data MongoDB
1 concept
MongoDB is a cross-platform, document-oriented non-relational database. It is the most feature-rich non-relational database and the product most similar to a relational database. The data structure it supports is very loose and is a format similar to JSON, so it can store more complex data types.
MongoDB mainly has the following concepts:
A document is equivalent to a record in a relational database
Multiple documents form a collection, which is equivalent to a table in a relational database.
Multiple collections are organized together as a database, and a MongoDB instance supports multiple databases.
Comparison of concepts in MongoDB and relational databases:
Spring Data MongoDB is the product of SpringData technology encapsulating mongodb-driver, which can operate MongoDB in a simpler way.
2 Install MongoDB
2.1. Install MongoDB
2.2. Install MongoDB visualization tool RoBo 3T
3.3. RoBo 3T connects to MongoDB and creates a database
3 Spring Data MongoDB project construction
1. Create a SpringBoot project and add the Spring Data MongoDB starter dependency when creating it.
2. Write the configuration file
spring:
data:
mongodb:
uri: mongodb://localhost:27017/数据库名
3. Create entity classes
@Document("article")
public class Article {
@Id
private Integer id;
private String title;
private String content;
// 省略 getter/setter,构造方法,tostring
}
4. Create a Repository interface to inherit the MongoRepository interface
5. Inject Repository into the test class
4 Common methods of Spring Data MongoDB
1. Methods inherited from the Repository interface
2. Paging query
3. Naming rule query
七、 Spring Data Solr
1 concept
Solr is a search engine tool built on top of Apache Lucene. The function is similar to ElasticSearch, and there are the following concepts in Solr:
collection/core: A collection of the same data format, which can be compared to a table in the database. It is called collection in a solr cluster and core in a stand-alone environment.
document: document is the most basic unit of Solr index and search, similar to a record in a relational database table.
filed: field, or domain, can be understood as a field in a table in the database.
Comparison of concepts in Solr and relational databases:
Note: Spring has stopped the maintenance of Spring Data Solr since 2020, and Spring recommends using ElasticSearch as a search engine. SpringBoot does not support the Spring Data Solr module after version 2.4.0, so we can simply learn it here.
2 Install Solr
1 Unzip the solr zip archive.
2 Enter the bin directory under the solr installation path, open the cmd console, and enter solr.cmd start to start solr
3 Visit http://localhost:8983/solr to enter the solr graphical management interface
3 Spring Data Solr Getting Started Case
1 create core
(1) Create a folder in server\solr under the solr installation directory to save core data
(2) Copy the server\solr\configsets\_default\conf folder under the solr installation directory to the newly created directory.
(3) Click add core on the solr graphical management interface to create a core
2 Create a springboot project, add the Spring Data Solr module, and the springboot version should not be higher than 2.4.0
3 Write the configuration file
spring:
data:
solr:
host: http://localhost:8983/solr/
4 Create entity class
@SolrDocument(solrCoreName = "product")
public class Product {
@Field
private String id;
@Field
private String productName;
@Field
private String productDesc;
// 省略 getter/setter,构造方法,tostring
}
5 Create a Repository interface to inherit the SolrCrudRepository interface
6 Inject the Repository and Template objects into the test class, and test the save method
4 Common methods of Spring Data Solr
1 Methods of the Template object
2 Methods inherited from the Repository interface
3 Pagination query
4 Naming rule query
Eight, Spring Data case
1 Case introduction Below we use a case to comprehensively use Spring Data technology. The case is based on the product management in the e-commerce website, involving product management, querying the latest products, comment management, product search and other functions. The following specific analysis:
Product data is divided into basic information and product details, which are stored in the product table and product detail table of mysql respectively.
The latest product query refers to the recently added products, and the promoted products can be displayed during actual development. relatively large number of visits,
Use redis storage. Commodity reviews have a large amount of data and low data value, so they are stored in mongodb. The full-text search is implemented using ES. In this case, data is directly inserted into ES. In actual development, logstash can be used to synchronize from the database.
2 Functional analysis
3 project construction
3.1 Software preparation
Open mysql, Redis, RedisDesktopManager, ElasticSearch, kibana, MongoDB, Robo 3t, and create a database in mysql.
3.2 Create a project
To create a Springboot project, the starting dependencies need to be introduced: spring data jpa, mysql driver, spring data elasticsearch, spring data redis, spring data mongodb, spring web
3.3 Configuration file
server:
port: 80
context-path: /
spring:
# 数据源
datasource:
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql:///shopping?serverTimezone=GMT%2b8
username: root
password: root
jpa:
database: MySQL
show-sql: true
generate-ddl: true
hibernate:
ddl-auto: update
naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy
# 解决属性使用驼峰命名法无法与数据库字段向匹配
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
redis:
# Redis 服务器主机。
host: localhost
# Redis 服务器端口。
port: 6379
jedis:
pool:
# 连接池在给定时间可以分配的最大连接数。
max-active: 8
# 连接池中空闲连接的最大数量。
max-idle: 8
# 连接池中空闲连接的最小数量。
min-idle: 0
elasticsearch:
rest:
uris: http://localhost:9200
data:
mongodb:
uri: mongodb://localhost:27017/product
4 Create entity class
产品实体类
@Entity
public class Product implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; // 主键
private String productName; // 产品名
private Double price; // 价格
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "data_id")
private ProductData productData; //产品详情
@Transient
private List<Comment> comments = new ArrayList(); //评论
}
产品详情实体类
@Entity
public class ProductData implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id; // 主键
private String productDesc;//产品详情
}
产品 ES 实体类
@Document(indexName = "product",replicas = 2,shards = 5)
public class ProductES {
@Id
@Field(type = FieldType.Text,index = true,store = true)
private Integer id;
@Field(type = FieldType.Text,index = true,store = true,analyzer =
"ik_smart",searchAnalyzer = "ik_smart")
private String productName; // 产品名
@Field(type = FieldType.Text,index = true,store = true,analyzer =
"ik_smart",searchAnalyzer = "ik_smart")
private String productDesc;// 产品介绍
@Field(type = FieldType.Double,index = false,store = true)
private Double price;
}
评论实体类
@Document("comment")
public class Comment implements Serializable {
@Id
private Integer id; // mongodb 不能实现主键自增
private Integer pid; // 产品 id
private String username; // 评论人
private String content; // 评论内容
}
5 Create a repository
public interface ProductRepository extends JpaRepository<Product, Integer>, JpaSpecificationExecutor<Product>
public interface ProductESRepository extends ElasticsearchRepository<ProductES,Integer>
public interface CommentRepository extends MongoRepository<Comment,Integer>
6 Create Controller
我们设计 resultful 风格的接口:
@PostMapping("/product")
@ResponseBody
public Result saveOrUpdateProduct(@RequestBody Product product) {
return null;
}
@DeleteMapping("/product/{id}")
@ResponseBody
public Result deleteProduct(@PathVariable Integer id) {
return null;
}
@GetMapping("/product/new")
@ResponseBody
public Result newProduct() {
return null;
}
@PostMapping("/comment")
@ResponseBody
public Result saveComment(@RequestBody Comment comment) {
return null;
}
@DeleteMapping("/comment/{id}")
@ResponseBody
public Result deleteComment(@PathVariable Integer id) {
return null;
}
@GetMapping("/product/{id}")
@ResponseBody
public Result findProduct(@PathVariable Integer id) {
return null;
}
@GetMapping("/product/search")
@ResponseBody
public Result search(String keyword, @RequestParam(defaultValue = "0") int page, @RequestParam(defaultValue = "5") int size) {
return null;
}
7 Write service business logic
There are many business logics, please refer to the accompanying code for specific codes
8 Use the postman tool to test the interface
postman is an interface debugging software. We can use it to send any http request conveniently