官方网址:https://www.elastic.co/cn/products/elasticsearch
Github:https://github.com/elastic/elasticsearch
优点
1.扩展性好,可部署上百台服务器集群,处理PB级数据。
2.近实时的去索引数据、搜索数据。
es和solr选择哪个?
1.如果你公司现在用的solr可以满足需求就不要换了。
2.如果你公司准备进行全文检索项目的开发,建议优先考虑elasticsearch,因为像Github这样大规模的搜索都在用它。
ElasticSearch原理
es在项目中的应用方式:
1)用户在前端搜索关键字
2)项目前端通过http方式请求项目服务端
3)项目服务端通过Http RESTful方式请求ES集群进行搜索
4)ES集群从索引库检索数据。
RestHighLevelClient介绍
RestHighLevelClient是Elasticsearch官方提供的Java高级REST客户端,它基于Java Low Level REST Client,提供了更多的接口和功能。相比于低级别客户端,RestHighLevelClient更加易用和灵活,可以更方便地进行索引、搜索、聚合等操作。同时,它也支持异步操作和连接池等特性,可以提高客户端的性能和稳定性。需要注意的是,RestHighLevelClient的版本需要与Elasticsearch集群的版本保持一致。
el架包
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>elasticsearch-rest-high-level-client</artifactId>
<version>6.2.1</version>
</dependency>
<dependency>
<groupId>org.elasticsearch</groupId>
<artifactId>elasticsearch</artifactId>
<version>6.2.1</version>
</dependency>
el配置
@Configuration
public class EsConfig {
//也可以使用application.yml文件来配置当前主机和端口
//那就要声明主机和端口属性
//使用注解value来获取yml文件中的主机和端口
@Value("${es.port}")
private String port;
@Value("${es.host}")
private String host;
@Bean
public RestHighLevelClient client() {
HttpHost httpHost = new HttpHost("127.0.0.1", 9200, "http");
return new RestHighLevelClient(RestClient.builder(httpHost));
}
}
使用java代码创建索引库
@Override
public void crateIndex() throws Exception {
//声明高级rest客户端
@Autowired
private RestHighLevelClient client;
//创建索引请求对象,声明索引名
CreateIndexRequest createIndexRequest = new CreateIndexRequest("tb_sku");
//创建索引的分片数量,副本数量
createIndexRequest.settings(Settings.builder()
.put("number_of_shards","1")
.put("number_of_replicas", "0"));
//设置你需要的列的映射
createIndexRequest.mapping("doc", "${...}", XContentType.JSON);
CreateIndexResponse response = client.indices()
.create(createIndexRequest, RequestOptions.DEFAULT);
System.out.println(response.isAcknowledged());
}
使用搜索引擎进行分页查询
//分页查询
public Page<Course> page(Integer index, Integer size) throws Exception{
//查询请求对象
SearchRequest searchRequest = new SearchRequest("xc_course");
searchRequest.types("doc");
//查询构建,设置查询方法(全部查询,分页查询,条件查询)
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//设置分页参数
searchSourceBuilder.from((index - 1) * size);
searchSourceBuilder.size(size);
//设置全部查询
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//过滤显示的列
searchSourceBuilder.fetchSource(new String[]
{"name","description","studymodel","price"},new String[]{});
//查询构建存储到请求对象中
searchRequest.source(searchSourceBuilder);
//执行请求并获取响应
SearchResponse searchResponse = client.search(searchRequest,
RequestOptions.DEFAULT);
//获取最外层
SearchHits hits = searchResponse.getHits();
Long totalHits = hits.getTotalHits();
System.out.println("总记录数:" + totalHits);
//获取用户数据
SearchHit[] searchHits = hits.getHits();
List<Course> list = new ArrayList<>();
for (SearchHit hit : searchHits) {
String id = hit.getId();
String json = hit.getSourceAsString();
Course course = JSON.parseObject(json, Course.class);
course.setId(id);
list.add(course);
}
Page<Course> page = new Page<>();
page.setIndex(index);
page.setSize(size);
page.setCount(totalHits.intValue());
page.setData(list);
return page;
}
多条件内容查询
/**
* 多条件内容查询
* @param keyword
* @param studymodel
* @param min
* @param max
* @throws Exception
*/
public void filter(String keyword,String studymodel, Double min, Double max) throws Exception{
SearchRequest searchRequest = new SearchRequest("xc_course");
searchRequest.types("doc");
//查询资源构建
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//创建组合查询对象
BoolQueryBuilder boolQuery = QueryBuilders.boolQuery();
//分词查询
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery(keyword, "name", "description");
multiMatchQueryBuilder.field("name",10);
boolQuery.must(multiMatchQueryBuilder);
//精准查
if(!StringUtils.isEmpty(studymodel)){
TermQueryBuilder termQuery = QueryBuilders.termQuery("studymodel", studymodel);
//组合条件
boolQuery.filter(termQuery);
}
if(!ObjectUtils.isEmpty(min) && !ObjectUtils.isEmpty(max)){
RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery("price");
rangeQuery.gte(min).lte(max);
//添加范围查询
boolQuery.filter(rangeQuery);
}
//添加排序
searchSourceBuilder.sort(new FieldSortBuilder("studymodel").order(SortOrder.DESC));
searchSourceBuilder.sort(new FieldSortBuilder("price").order(SortOrder.ASC));
//创建高亮对象
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.preTags("<span style='color:red;'>");
highlightBuilder.postTags("</span>");
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
highlightBuilder.fields().add(new HighlightBuilder.Field("description"));
searchSourceBuilder.highlighter(highlightBuilder);
//设置查询构建
searchSourceBuilder.query(boolQuery);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit searchHit : searchHits) {
Map<String, Object> sourceAsMap = searchHit.getSourceAsMap();
//所有的高亮对象
Map<String, HighlightField> mapField = searchHit.getHighlightFields();
//获取name高亮数据
HighlightField nameField = mapField.get("name");
if(!ObjectUtils.isEmpty(nameField)){
Text[] nameText = nameField.fragments();
StringBuffer namebuf = new StringBuffer();
for (Text text : nameText) {
namebuf.append(text.toString());
}
sourceAsMap.put("name",namebuf.toString());
}
//获取description高亮数据
HighlightField descriptionField = mapField.get("description");
if(!ObjectUtils.isEmpty(descriptionField)){
Text[] descriptionText = descriptionField.fragments();
StringBuffer descriptionbuf = new StringBuffer();
for (Text text : descriptionText) {
descriptionbuf.append(text.toString());
}
sourceAsMap.put("description",descriptionbuf.toString());
}
System.out.println(sourceAsMap);
}
}