前言和参考资料
官方网站 https://www.elastic.co/cn/elasticsearch/
https://docs.spring.io/spring-data/elasticsearch/docs/4.1.3/reference/html/#reference
2万字详解,彻底讲透 全文搜索引擎 Elasticsearch
SpringBoot+ElasticSearch 实现模糊查询,批量CRUD,排序,分页,高亮
Elasticsearch 中文官方博客 https://blog.csdn.net/UbuntuTouch
快速上手(操作ElasticsearchRestTemplate )
第一步:添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>
第二步:根据依赖确定版本,从官网学习相关内容。
https://docs.spring.io/spring-data/elasticsearch/docs/4.1.3/reference/html/#reference
第三步:修改配置文件
spring:
elasticsearch:
rest:
uris: ip:port
第四步:复制以下代码到项目中
@RestController
@RequestMapping("person")
@Api(value = "Person Operation")
public class PersonOperationController {
@Autowired
ElasticsearchRestTemplate template;
/**
* 根据id查询Person Deprecated
*
* @param id
* @return
*/
@GetMapping("/get/{id}")
public Person findById(@PathVariable("id") Long id) {
return template.queryForObject(GetQuery.getById(id.toString()), Person.class);
}
/**
* 根据id查询Person V2
*
* @param id
* @return
*/
@GetMapping("/get/v2/{id}")
public Person findByIdV2(@PathVariable("id") Long id) {
//1
// return template.get(String.valueOf(id), Person.class);
//2
return template.get(String.valueOf(id), Person.class, PersonConstant.DESCRIBE);
}
/**
* 将 person 存入 es
*
* @param person
* @return
*/
@PostMapping("/index")
public String index(@RequestBody Person person) {
//query
IndexQuery indexQuery = new IndexQueryBuilder()
.withId(person.getId().toString())
.withObject(person)
.build();
return template.index(indexQuery, PersonConstant.DESCRIBE);
}
/**
* 将 personList 存入 es
*
* @param personList
* @return
*/
@PostMapping("bulkIndex")
public List<IndexedObjectInformation> bulkIndex(@RequestBody List<Person> personList) {
List<IndexQuery> indexQueryList = personList.stream().map(person -> new IndexQueryBuilder()
.withId(person.getId().toString())
.withObject(person)
.build()).collect(Collectors.toList());
return template.bulkIndex(indexQueryList, PersonConstant.DESCRIBE);
}
/**
* 删除 用户
*
* @param id
* @return
*/
@DeleteMapping("delete")
public String delete(Integer id) {
return template.delete(String.valueOf(id), PersonConstant.DESCRIBE);
}
/**
* 根据文档更新
*
* @param person
* @return
*/
@PostMapping("/update/Document")
public UpdateResponse updateDocument(@RequestBody Person person) {
String id = String.valueOf(person.getId());
// String id = UUID.randomUUID().toString();
String personJson = JSONUtil.toJsonStr(person);
//根据json构建Document对象
Document document = Document.parse(personJson);
//如果传uuid会导致下面的错误,所以需要传document id
// org.elasticsearch.ElasticsearchStatusException:
// Elasticsearch exception [type=document_missing_exception, reason=[_doc][56bc3c13-d238-41a8-9f71-483fd0bda61c]: document missing]
UpdateQuery updateQuery = UpdateQuery.builder(id)
.withDocument(document)
.build();
return template.update(updateQuery, PersonConstant.DESCRIBE);
}
/**
* 根据脚本更新
*
* @param person
* @return
*/
@PostMapping("/update/script")
public UpdateResponse updateScript(@RequestBody Person person) {
String id = String.valueOf(person.getId());
//ctx固定写法,_source代表文档,name代表只修改name这个字段
String script = "ctx._source.name=params.name;";
script = script + "ctx._source.age=params.age;";
Map<String, Object> params = new HashMap<>();
//params是要传入修改的值
params.put("name", person.getName());
params.put("age", person.getAge());
UpdateQuery updateQuery = UpdateQuery.builder(id)
.withScript(script)
.withParams(params)
.build();
return template.update(updateQuery, PersonConstant.DESCRIBE);
}
}
PersonConstant
public class PersonConstant {
/**
* index name
*/
public static final String INDEX_NAME = "person";
/**
* the index where the object is stored.
*/
public static final IndexCoordinates DESCRIBE = IndexCoordinates.of(INDEX_NAME);
}
Person 类
@Document(indexName = PersonConstant.INDEX_NAME)
@Data
public class Person {
@Id
Long id;
String name;
String user;
String message;
Long uid;
Long age;
String city;
String province;
String country;
String address;
Map<String, String> location;
}
先调用save方法存入es,然后使用findById查询。
Tips:
如果调用没有IndexCoordinates的方法,必须在实体类使用@Document注解并指定indexName。
例如,如果findByIdV2这个方法使用 //1,则必须使用注解。如果使用//2则不需要使用注解。
错误描述如下:
org.elasticsearch.ElasticsearchStatusException:
Elasticsearch exception [type=index_not_found_exception, reason=no such index [Person]]
- update操作支持两种方式withDocument和withScript,不支持同时使用两种方式会报错,当使用withScript需要搭配withParams使用
index(索引)
快速上手
对索引的操作通过 IndexOperations 来实现。
@RestController
@RequestMapping("index")
@Api(tags = "IndexOperations(索引)相关接口")
public class IndexController {
@Autowired
ElasticsearchRestTemplate template;
//创建索引
@Deprecated
@GetMapping("/createIndex")
public boolean createIndex(String indexName) {
return template.createIndex(indexName);
}
@GetMapping("/v2/createIndex")
public boolean createIndexV2(String indexName) {
IndexCoordinates indexCoordinates = IndexCoordinates.of(indexName);
IndexOperations indexOperations = template.indexOps(indexCoordinates);
return indexOperations.create();
}
//删除索引
@Deprecated
@GetMapping("/deleteIndex")
public boolean deleteIndex(String indexName) {
return template.deleteIndex(indexName);
}
@GetMapping("/v2/deleteIndex")
public boolean deleteIndexV2(String indexName) {
IndexCoordinates indexCoordinates = IndexCoordinates.of(indexName);
IndexOperations indexOperations = template.indexOps(indexCoordinates);
return indexOperations.delete();
}
//是否存在索引
@Deprecated
@GetMapping("/existIndex")
public boolean existIndex(String indexName) {
return template.indexExists(indexName);
}
@GetMapping("/v2/existIndex")
public boolean existIndexV2(String indexName) {
IndexCoordinates indexCoordinates = IndexCoordinates.of(indexName);
IndexOperations indexOperations = template.indexOps(indexCoordinates);
return indexOperations.exists();
}
//刷新索引
@Deprecated
@GetMapping("/refresh")
public void refresh(String indexName) {
IndexCoordinates indexCoordinates = IndexCoordinates.of(indexName);
template.refresh(indexCoordinates);
}
@GetMapping("/v2/refresh")
public void refreshV2(String indexName) {
IndexCoordinates indexCoordinates = IndexCoordinates.of(indexName);
IndexOperations indexOperations = template.indexOps(indexCoordinates);
indexOperations.refresh();
}
}
Tips
- 创建索引:创建成功返回true,如果名称是大写会报错 must be lowercase
Elasticsearch exception[type=invalid_index_name_exception,reason=Invalid index name [Person2], must be lowercase]
- 删除索引:删除成功返回true,删除失败和重复删除返回false。
- 存在索引:存在返回true,不存在返回false。
- 刷新索引:无返回值。
Document (文档)
对应MySQL相当于一条条的记录。
https://www.elastic.co/guide/en/elasticsearch/reference/current/docs.html
5. Elasticsearch Clients
https://docs.spring.io/spring-data/elasticsearch/docs/4.1.3/reference/html/#elasticsearch.clients
RestClient
5.2. High Level REST Client(高级REST客户端)
7. Elasticsearch Operations (ES 操作)
https://docs.spring.io/spring-data/elasticsearch/docs/4.1.3/reference/html/#elasticsearch.operations
重要的接口
- IndexOperations,索引相关操作
- DocumentOperations,文档相关操作。
- SearchOperations,搜索操作。
- ElasticsearchOperations,结合了 DocumentOperations 和 SearchOperations 接口。
7.1. ElasticsearchTemplate
Tips: Usage of the ElasticsearchTemplate is deprecated as of version 4.0, use ElasticsearchRestTemplate instead.
4.0版本以后推荐使用 ElasticsearchRestTemplate 。
7.2. ElasticsearchRestTemplate
7.6. Queries(查询)
Query is an interface and Spring Data Elasticsearch provides three implementations:
- CriteriaQuery
- StringQuery
- NativeSearchQuery.
7.6.1. CriteriaQuery(标准查询)
Tips: when talking about AND or OR when combining criteria keep in mind, that in Elasticsearch AND are converted to a must condition and OR to a should。
and 解释为 must ,or 解释为 should