介绍
Elasticsearch是一个实时的分布式搜索分析引擎,底层基于Lucene实现。它提供了一个分布式多用户能力的全文搜索引擎,并且客户端可以使用标准的RESTful进行访问。Elasticsearch是用Java开发的,并作为Apache许可条款下的开放源码发布,是当前流行的企业级搜索引擎。设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。
传统的搜索做法主要以是基于系统或应用的查询功能进行查找,或者使用数据库的模糊查询等机制来完成。这些方式相对简单,对于少量数据来说操作性比较方便。但对于海量数据,性能就会急剧下降导致不能及时响应,且不易于扩展。而使用搜索引擎的好处在于,它可以存储非结构化的数据,进行相关的排序、过滤以及分词等功能,快速检索我们需要的数据信息。
可以从官网下载最新版本: https://www.elastic.co/cn/products/
使用
Maven
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>7.15.2</version>
</dependency>
案例
EsClientUtils
public class EsClientUtils {
private static String host = "127.0.0.1";
private static Integer port = 9200;
public static RestHighLevelClient getClient() {
RestClientBuilder builder = RestClient
.builder(new HttpHost(host, port));
return new RestHighLevelClient(builder);
}
}
IndexDemo
操作index
public class IndexDemo {
/**
* 创建索引
* @param index
*/
public void createIndex(String index) {
try(RestHighLevelClient client = EsClientUtils.getClient()){
//构建创建索引的请求对象
CreateIndexRequest request = new CreateIndexRequest(index);
//通过客户端发送请求到es完成创建,并返回一个响应对象
CreateIndexResponse response = client.indices()
.create(request, RequestOptions.DEFAULT);
//输出ack是否创建成功
String ack = response.isAcknowledged() ? "创建成功": "创建失败";
log.info(ack);
}catch(Exception e) {
throw new RuntimeException("创建索引失败", e);
}
}
/**
* 删除索引
* @param index
*/
public void deleteIndex(String index) {
try(RestHighLevelClient client = EsClientUtils.getClient()) {
//创建删除索引请求
DeleteIndexRequest request = new DeleteIndexRequest(index);
//发送请求并返回响应对象
AcknowledgedResponse response = client.indices()
.delete(request, RequestOptions.DEFAULT);
//输出ack是否删除成功
String ack = response.isAcknowledged() ? "删除成功": "删除失败";
log.info(ack);
}catch(Exception e) {
throw new RuntimeException("删除索引失败", e);
}
}
/**
* 关闭索引
* @param index
*/
public void closeIndex(String index) {
try(RestHighLevelClient client = EsClientUtils.getClient()) {
//创建关闭索引的请求对象
CloseIndexRequest request = new CloseIndexRequest(index);
//发送请求并返回响应对象
CloseIndexResponse response = client.indices()
.close(request, RequestOptions.DEFAULT);
String ack = response.isAcknowledged() ? "关闭成功" : "关闭失败";
log.info(ack);
}catch (Exception e) {
throw new RuntimeException("关闭索引失败", e);
}
}
/**
* 打开索引
* @param index
*/
public void openIndex(String index) {
try(RestHighLevelClient client = EsClientUtils.getClient()) {
OpenIndexRequest request = new OpenIndexRequest(index);
OpenIndexResponse response = client.indices()
.open(request, RequestOptions.DEFAULT);
String ack = response.isAcknowledged() ? "打开成功" : "打开失败";
log.info(ack);
}catch (Exception e) {
throw new RuntimeException("打开索引失败", e);
}
}
/**
* 为指定的index创建mappings
* @param index
*/
public void createMapping(String index) {
try(RestHighLevelClient client = EsClientUtils.getClient()) {
//创建一个构建mapping的请求对象
PutMappingRequest request = new PutMappingRequest(index);
//使用XContentBuilder来构建mapping
XContentBuilder builder = XContentFactory.jsonBuilder();
builder.startObject();
{
builder.startObject("properties");
{
//name属性
builder.startObject("name");
{
//设置字段类型
builder.field("type", "keyword");
}
builder.endObject();
//age属性
builder.startObject("age");
{
builder.field("type", "integer");
}
builder.endObject();
//birthplace属性
builder.startObject("birthplace");
{
builder.field("type", "text");
builder.field("analyzer", "ik_max_word");
}
builder.endObject();
}
builder.endObject();
}
builder.endObject();
//将builder设置到请求对象中
request.source(builder);
//发送请求并返回响应
AcknowledgedResponse response = client.indices()
.putMapping(request, RequestOptions.DEFAULT);
String ack = response.isAcknowledged() ? "创建成功" : "创建失败";
log.info(ack);
}catch (Exception e) {
throw new RuntimeException("创建mappings失败", e);
}
}
}
DocumentDemo
操作文档
public class DocumentDemo {
/**
* 创建文档
* @param index 索引
* @param id 唯一标识
* @param map map数据集合
*/
public void createDoc(String index, String id,
Map<String, Object> map) {
try(RestHighLevelClient client = EsClientUtils.getClient()) {
//创建IndexRequest请求对象
IndexRequest request = new IndexRequest(index)
.id(id).source(map);
//发送请求并返回响应对象
IndexResponse response = client
.index(request, RequestOptions.DEFAULT);
String docId = response.getId();
log.info("文档ID:" + docId);
}catch (Exception e) {
throw new RuntimeException("创建文档失败", e);
}
}
/**
* 根据id查找文档
* @param index
* @param id
* @return
*/
public Map<String, Object> getDocById(String index,
String id) {
try(RestHighLevelClient client = EsClientUtils.getClient()) {
GetRequest request = new GetRequest(index, id);
GetResponse response = client.get(request,
RequestOptions.DEFAULT);
return response.getSource();
}catch (Exception e) {
throw new RuntimeException("查找文档失败", e);
}
}
/**
* 全文检索
* @param index 索引
* @param field 搜索的字段
* @param params 查询参数
* @return
*/
public List<Map<String, Object>> search(String index,
String field,
String params) {
try(RestHighLevelClient client = EsClientUtils.getClient()) {
//创建搜索的请求对象
SearchRequest request = new SearchRequest(index);
//创建检索器,创建检索的条件和类型
SearchSourceBuilder builder = new SearchSourceBuilder();
//通过QueryBuilder创建不同的检索类型(term、match、bool)
//并传入字段和查询参数,这里使用的是布隆查询器
BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
//设置查询参数,使用should子查询结合match检索
queryBuilder.should(QueryBuilders.matchQuery(field, params));
//将布隆查询器设置给SearchSourceBuilder
builder.query(queryBuilder);
//将builder设置到请求对象中
request.source(builder);
//发送请求进行检索并返回响应对象
SearchResponse response = client.search(request,
RequestOptions.DEFAULT);
//从SearchResponse中获取命中的检索记录
SearchHits hits = response.getHits();
List<Map<String, Object>> results = new ArrayList<>();
hits.forEach(hit -> {
//将每一条命中的记录转换为map集合并放入list中
results.add(hit.getSourceAsMap());
});
return results;
}catch (Exception e) {
throw new RuntimeException("检索失败", e);
}
}
}