Spring Data ElasticSearch
是spring-data成员里面的又一个项目,spring-data-xxx
至力与简化我们持久层的开发
,如有
spring-data-redis
,spring-data-jdbc
,spring-data-mongodb
spring-data-jpa
,xxxxRepository
,(然后通过规范书写我们的查询方法),又或者是可以继承他提供好的Repository
,如:CrudRepository
里面自带增加改查一下简单的操作。最后通过我们创建的Repository,来进行数据的操作。具体的可以参照我另外一篇博客spring-data-jpa,里面有更详细的介绍,但是 其实底层都可都通过xxxxTemplate
来操作。这篇文章的主要内容,也就是记录一下ElasticsearchTemplate
首先你的电脑上有安装Elasticsearch
,安装很简单,可以参照我上篇博客Elasticsearch的介绍
(1)、创建一个工程之后引入主要依赖
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
(2)、配置文件application.yml
server:
port: 9007
spring:
application:
name: onezero-search
data:
elasticsearch:
cluster-nodes: 127.0.0.1:9300
(3)、创建测试的类Book
记得标注 注解
@Document 标注文档对象的类型
@id 标注文档的主键
package com.onezero.serach.bean;
import org.springframework.data.annotation.Id;
import org.springframework.data.elasticsearch.annotations.Document;
/**
* @author hao
* @create 2019-07-20 ${TIM}
*/
@Document(indexName = "bookstore", type="book" ) //indexName设置索引库的名称 type设置文档的类型
public class Book {
//标识主键
@Id
private String id; //编号
private String bookName; //书名
private String content; //内容主题
private int pagecount; //多少页
public Book(String id, String bookName, String content, int pagecount) {
this.id = id;
this.bookName = bookName;
this.content = content;
this.pagecount = pagecount;
}
public Book() {
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public int getPagecount() {
return pagecount;
}
public void setPagecount(int pagecount) {
this.pagecount = pagecount;
}
}
(4)、开始测试
添加文档对象
@Test
public void testinsert() {
IndexQueryBuilder builder = new IndexQueryBuilder();
for (int i = 0; i < 10; i++) {
String id = "00"+i;
template.index(builder.withObject(new Book(id,i+"号变形金刚","这是讲述汽车人与狂派之间的故事第"+i+"回",10*i)).build());
}
}
}
查询文档对象
ElasticsearchTemplate多个批量查询的重载方法
@Override
//封装查询对象 类似于hibernate的CriteriaQuery 查询对象
public <T> List<T> queryForList(CriteriaQuery query, Class<T> clazz) {
return queryForPage(query, clazz).getContent();
}
@Override
public <T> List<T> queryForList(StringQuery query, Class<T> clazz) {
return queryForPage(query, clazz).getContent();
}
@Override
public <T> List<T> queryForList(SearchQuery query, Class<T> clazz) {
return queryForPage(query, clazz).getContent();
}
queryForList(CriteriaQuery query, Class clazz)
进行查询。查询所有
@Test
public void testfindAll(){
//创建查询对象
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria());
List<Book> books = template.queryForList(criteriaQuery, Book.class);
for (Book book : books) {
System.out.println(book);
}
}
输出:
Book{id='003', bookName='3号变形金刚', content='这是讲述汽车人与狂派之间的故事第3回', pagecount=30}
Book{id='005', bookName='5号变形金刚', content='这是讲述汽车人与狂派之间的故事第5回', pagecount=50}
Book{id='008', bookName='8号变形金刚', content='这是讲述汽车人与狂派之间的故事第8回', pagecount=80}
Book{id='004', bookName='4号变形金刚', content='这是讲述汽车人与狂派之间的故事第4回', pagecount=40}
Book{id='007', bookName='7号变形金刚', content='这是讲述汽车人与狂派之间的故事第7回', pagecount=70}
Book{id='009', bookName='9号变形金刚', content='这是讲述汽车人与狂派之间的故事第9回', pagecount=90}
Book{id='006', bookName='6号变形金刚', content='这是讲述汽车人与狂派之间的故事第6回', pagecount=60}
Book{id='000', bookName='0号变形金刚', content='这是讲述汽车人与狂派之间的故事第0回', pagecount=0}
Book{id='001', bookName='1号变形金刚', content='这是讲述汽车人与狂派之间的故事第1回', pagecount=10}
Book{id='002', bookName='2号变形金刚', content='这是讲述汽车人与狂派之间的故事第2回', pagecount=20}
查询bookName 这个字段 以1开始的数据
@Test
public void testQuery1(){
//构建查询对象
Criteria criteria = new Criteria("bookName").startsWith("1");
List<Book> books = template.queryForList(new CriteriaQuery(criteria), Book.class);
print(books);
}
输出:
Book{id='001', bookName='1号变形金刚', content='这是讲述汽车人与狂派之间的故事第1回', pagecount=10}
查询某字段在一定范围内的数据
// 查询pagecount在 30-70区间的数据
@Test
public void testQuery5(){
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria("pagecount").between(30,70));
List<Book> list = template.queryForList(criteriaQuery, Book.class);
print(list);
}
输出:
Book{id='003', bookName='3号变形金刚', content='这是讲述汽车人与狂派之间的故事第3回', pagecount=30}
Book{id='005', bookName='5号变形金刚', content='这是讲述汽车人与狂派之间的故事第5回', pagecount=50}
Book{id='004', bookName='4号变形金刚', content='这是讲述汽车人与狂派之间的故事第4回', pagecount=40}
Book{id='007', bookName='7号变形金刚', content='这是讲述汽车人与狂派之间的故事第7回', pagecount=70}
Book{id='006', bookName='6号变形金刚', content='这是讲述汽车人与狂派之间的故事第6回', pagecount=60}
小结:CriteriaQuery对象,适合添加精确的数据,来封装成查询对象,然后进行查询
queryForList(SearchQuery query, Class clazz)
进行查询。term 对应字段精确查询(不进行分词)
/**
* 某字段 精确查询 term查询
*/
@Test
public void testQuery2(){
List<Book> lsit = template.queryForList(new NativeSearchQueryBuilder().withQuery(termQuery("bookName", "1号变形金刚")).build(), Book.class);
print(lsit);
}
对应字段模糊查询
// 对应字段 模糊查询 查出所有
@Test
public void testQuery3(){
List<Book> books = template.queryForList(new NativeSearchQueryBuilder().withQuery(matchQuery("bookName", "变形金刚")).build(), Book.class);
print(books);
}
全字段字符串检索
// 全文检索 与金刚相关的 文档对象
@Test
public void testQuery4(){
List<Book> list = template.queryForList(new NativeSearchQueryBuilder().withQuery(queryStringQuery("金刚")).build(), Book.class);
print(list);
}
查询内容 模糊查询
//查找 bookName 模糊匹配 变形的
@Test
public void testQuery7(){
List<Book> list = template.queryForList(new NativeSearchQueryBuilder().withQuery(matchQuery("bookName", "变形")).build(), Book.class);
print(list);
}
某查询内容 在多个字段中的match匹配
/**
* 内容 match多字段
* @param books
*/
@Test
public void testQuery6(){
List<Book> list = template.queryForList(new NativeSearchQueryBuilder().withQuery(multiMatchQuery("金刚", "bookName", "content")).build(), Book.class);
print(list);
}
}
使用pageable
,也就是我们在查询的时候 添加我们的分页。例如:
@Test
public void testfindAll(){
// page: 代表第几页 从0开始
// size: 代表每页的数量
Pageable pageable = PageRequest.of(2,3);
//创建查询对象
CriteriaQuery criteriaQuery = new CriteriaQuery(new Criteria()).setPageable(pageable);
List<Book> books = template.queryForList(criteriaQuery, Book.class);
for (Book book : books) {
System.out.println(book);
}
}
文章开头提到过,我们的spring-data-xxx,还可以使用这种接口声明的方式,这种方式及其简单,只需声明 然后用它提供好的接口方法就可以了。这里就不详细介绍。
@NoRepositoryBean
public interface ElasticsearchRepository<T, ID extends Serializable> extends ElasticsearchCrudRepository<T, ID> {
<S extends T> S index(S entity);
Iterable<T> search(QueryBuilder query);
Page<T> search(QueryBuilder query, Pageable pageable);
Page<T> search(SearchQuery searchQuery);
Page<T> searchSimilar(T entity, String[] fields, Pageable pageable);
void refresh();
Class<T> getEntityClass();
}
继承ElasticsearchRepository
也就有了上述方法
public interface BookRepository extends ElasticsearchRepository<Book,String> {
}