elasticsearch的crud以及全文检索
需引进依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-elasticsearch</artifactId> </dependency>
@Autowired
private RestHighLevelClient restHighLevelClient;
新增or修改
/**
* 存储数据到es库中
* 根据id进行修改,如果id不存在就新增
*
* @throws IOException
*/
@Test
public void addOrUpdate() throws IOException {
//自定义es库 posts
IndexRequest request = new IndexRequest("jd_goods");
//新增时指定id
//request.id("5mBdnoQBz6yli7CstT1b");
Good content = new Good();
content.setTitle("java中级教程");
content.setImg("img");
content.setPrice(88.88d);
String str = JSON.toJSONString(content);
request.source(str, XContentType.JSON);
IndexResponse index = restHighLevelClient.index(request, RequestOptions.DEFAULT);
System.out.println(index);
}
注意:新增时没有添加id的话es会默认生成id的
修改数据
/**
* 修改数据
* @throws IOException
*/
@Test
public void update() throws IOException {
Good content = new Good();
content.setImg("http...jpg");
content.setTitle("serene");
content.setPrice(105.88d);
String str = JSON.toJSONString(content);
UpdateRequest request = new UpdateRequest("jd_goods", "2RDDwogBHZ9fuSiHmZT6");
request.doc(str, XContentType.JSON);
UpdateResponse response = restHighLevelClient.update(request, RequestOptions.DEFAULT);
System.out.println(response);
}
删除
/** * 根据id删除 * * @throws IOException */ @Test public void delete() throws IOException { //自定义es库 posts DeleteRequest request = new DeleteRequest("posts"); request.id("LmAanoQBz6yli7CsZT1C"); DeleteResponse index =restHighLevelClient.delete(request, RequestOptions.DEFAULT);
System.out.println(index);
}
查询详情
/**
* 根据id查询详情
*
* @throws IOException
*/
@Test
public void query() throws IOException {
//自定义es库 posts
GetRequest request = new GetRequest("posts");
request.id("LGAZnoQBz6yli7CsRD3u");
GetResponse index = esClientConfig.restHighLevelClient().get(request, RequestOptions.DEFAULT);
System.out.println(index);
}
全文检索 MultiQuery
/**
* 单字段、多字段全文检索 MultiQuery
*
* @throws IOException
*/
@Test
public void demo01() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
//matchQuery全文检索
searchSourceBuilder.query(QueryBuilders.matchQuery("description", "很好用").minimumShouldMatch("70%"));
//多字段联合搜索MatchQuery "80%"表示,三个词在文档的匹配占比为80%,即3*0.8=2.4,向下取整得2,表 示至少有两个词在文档中要匹配成功
//searchSourceBuilder.query(QueryBuilders.multiMatchQuery(keyword, "name", "description").minimumShouldMatch("80%"));
//提升 boost 设置 name 10倍权重 比重越高的域当他符合条件时计算的得分越高
//searchSourceBuilder.query(QueryBuilders.multiMatchQuery(keyword, "name", "description").field("name", 10));
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
ArrayList<Map<String, Object>> list = new ArrayList<>();
for (SearchHit documentFields : searchResponse.getHits().getHits()) {
list.add(documentFields.getSourceAsMap());
}
System.out.println(list);
}
布尔查询 BoolQuery
/**
* 布尔查询 BoolQuery
* <p>
* must: 相当于 “AND” 包含
* should: 相当于 "OR" 或者
* mustNot:相当于“NOT” 不包含
* termQuery:精确搜索
*
* @throws IOException
*/
@Test
public void demo02() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 首先构造多关键字查询条件
MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("很好用的一款", "name", "description").field("name", 10);
// 然后构造精确匹配查询条件
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("studymodel", 201001);
// 组合两个条件,组合方式为 must 全满足
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(matchQueryBuilder);
boolQueryBuilder.should(termQueryBuilder);
// 将查询条件封装给查询对象
searchSourceBuilder.query(boolQueryBuilder);
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
ArrayList<Map<String, Object>> list = new ArrayList<>();
for (SearchHit documentFields : searchResponse.getHits().getHits()) {
list.add(documentFields.getSourceAsMap());
}
System.out.println(list);
}
条件过滤 filter
/**
* 条件过滤
* <p>
* termQuery:精准匹配查询
* rangeQuery:范围查询
*
* @throws IOException
*/
@Test
public void demo03() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 首先构造多关键字查询条件
MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("标题", "name", "description").field("name", 10);
// 然后构造精确匹配查询条件
TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("studymodel", 201001);
// 组合两个条件,组合方式为 must 全满足
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(matchQueryBuilder);
boolQueryBuilder.should(termQueryBuilder);
//注意:range和term一次只能对一个Field设置范围过虑
// 通过布尔查询来构造过滤查询 指定值查询
boolQueryBuilder.filter(QueryBuilders.termQuery("studymodel", "201001"));
//大于多少 小于多少
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100000));
// 将查询条件封装给查询对象
searchSourceBuilder.query(boolQueryBuilder);
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
ArrayList<Map<String, Object>> list = new ArrayList<>();
for (SearchHit documentFields : searchResponse.getHits().getHits()) {
list.add(documentFields.getSourceAsMap());
}
System.out.println(list);
}
排序 sort
/**
* 排序
*
* @throws IOException
*/
@Test
public void demo04() throws IOException {
// 搜索请求对象
SearchRequest searchRequest = new SearchRequest("goods");
// 指定类型
//searchRequest.types("_doc");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 搜索方式
// 添加条件到布尔查询
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
// 通过布尔查询来构造过滤查询
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100000));
// 将查询条件封装给查询对象
searchSourceBuilder.query(boolQueryBuilder);
// 向搜索请求对象中设置搜索源
searchRequest.source(searchSourceBuilder);
// 设置排序规则 当第一排序值一样时执行第二排序 第二排序值过大时也排在前面
// 降序
searchSourceBuilder.sort("studymodel.keyword", SortOrder.DESC); // 第一排序规则
// 升序
searchSourceBuilder.sort("price", SortOrder.ASC); // 第二排序规则
// 执行搜索,向ES发起http请求
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
ArrayList<Map<String, Object>> list = new ArrayList<>();
for (SearchHit documentFields : searchResponse.getHits().getHits()) {
list.add(documentFields.getSourceAsMap());
}
System.out.println(list);
// 搜索结果
SearchHits hits = searchResponse.getHits();
// 匹配到的总记录数
System.out.println("总条数:" + hits.getTotalHits().value);
}
搜索关键字高亮
/**
* 搜索关键字高亮
*
* @throws IOException
*/
@Test
public void demo05() throws IOException {
SearchRequest searchRequest = new SearchRequest("goods");
// 搜索源构建对象
SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
// 首先构造多关键字查询条件
MultiMatchQueryBuilder matchQueryBuilder = QueryBuilders.multiMatchQuery("java", "description").field("name", 10);
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
boolQueryBuilder.must(matchQueryBuilder);
//过滤 大于多少 小于多少
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100000));
// 将查询条件封装给查询对象
searchSourceBuilder.query(boolQueryBuilder);
searchSourceBuilder.timeout(new TimeValue(60, TimeUnit.SECONDS));
//高亮搜索
HighlightBuilder highlightBuilder = new HighlightBuilder();
highlightBuilder.field("name");
//显示多个高亮
highlightBuilder.requireFieldMatch(false);
// 高亮前缀
highlightBuilder.preTags("<sqan style ='color:red'>");
// 高亮后缀
highlightBuilder.postTags("</sqan>");
searchSourceBuilder.highlighter(highlightBuilder);
searchRequest.source(searchSourceBuilder);
SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
//解析结果
ArrayList<Map<String, Object>> list = new ArrayList<>();
for (SearchHit hit : searchResponse.getHits().getHits()) {
// 原文档内容
Map<String, Object> sourceAsMap = hit.getSourceAsMap();
// 原名称
String name = (String) sourceAsMap.get("name");
// 获取高亮查询的内容。如果存在,则替换原来的name
Map<String, HighlightField> highlightFields = hit.getHighlightFields();
if (highlightFields != null) {
HighlightField nameField = highlightFields.get("name");
if (nameField != null) {
Text[] fragments = nameField.getFragments();
StringBuilder stringBuffer = new StringBuilder();
for (Text str : fragments) {
stringBuffer.append(str.string());
}
name = stringBuffer.toString();
}
//高亮字段替换成原来的内容
sourceAsMap.put("name", name);
}
list.add(sourceAsMap);
}
System.out.println(list);
}
postman查询
查询所有索引
localhost:9200/_cat/indices?v
后面加v表示查询的更详细
查询某个索引中的数据
localhost:9200/jd_goods/_search
条件
{ "from": 1, "size": 10 }
复合查询
{{es}}/ckf_index/_search
条件
{ "query": { "bool": { "must": [ { "match": { "title": "Elasticsearch" } }, { "match": { "category": "搜索引擎" } } ] } }, "from": 0, "size": 10 }