一:准备工作
1.1配置文件
server:
port: ${port:40100}
spring:
application:
name: xc-search-service
xuecheng:
elasticsearch:
hostlist: ${eshostlist:127.0.0.1:9200} #多个结点中间用逗号分隔
1.2配置类
@Configuration
public class ElasticsearchConfig {
@Value("${xuecheng.elasticsearch.hostlist}")
private String hostlist;
@Bean
public RestHighLevelClient restHighLevelClient(){
//解析hostlist配置信息
String[] split = hostlist.split(",");
//创建HttpHost数组,其中存放es主机和端口的配置信息
HttpHost[] httpHostArray = new HttpHost[split.length];
for(int i=0;i
二:索引库的操作
测试类中要注入上一步定义好的bean
2.1新建索引库
@Test
public void testCreateIndex() throws IOException {
//创建索引对象
CreateIndexRequest createIndexRequest=new CreateIndexRequest("xc_course");
//设置参数
createIndexRequest.settings(Settings.builder().put("number_of_shards","1").put("number_of_replicas","0"));
//指定映射
createIndexRequest.mapping("doc","n" +
"\"properties\": {\n" +
"\"name\": {\n" +
"\"type\": \"text\",\n" +
"\"analyzer\":\"ik_max_word\",\n" +
"\"search_analyzer\":\"ik_smart\"\n" +
"},\n" +
"\"description\": {\n" +
"\"type\": \"text\",\n" +
"\"analyzer\":\"ik_max_word\",\n" +
"\"search_analyzer\":\"ik_smart\"\n" +
"},\n" +
"\"pic\":{\n" +
"\"type\":\"text\",\n" +
"\"index\":false\n" +
"},\n" +
"\"studymodel\":{\n" +
"\"type\":\"text\"\n" +
"}\n" +
"}\n" +
"}", XContentType.JSON);
//操作索引的客户端
IndicesClient indices = restHighLevelClient.indices();
//执行添加所以有
CreateIndexResponse response = indices.create(createIndexRequest);
//得到响应
boolean acknowledged = response.isAcknowledged();
System.out.println(acknowledged);
}
2.2删除索引库
@Test
public void testDeleteIndex() throws IOException {
//创建索引对象
DeleteIndexRequest deleteIndexRequest=new DeleteIndexRequest("xc_course");
//操作索引的客户端
IndicesClient indices = restHighLevelClient.indices();
//执行删除
DeleteIndexResponse delete = indices.delete(deleteIndexRequest);
//返回结果
boolean acknowledged = delete.isAcknowledged();
System.out.println(acknowledged);
}
三:文档的操作
3.1添加文档
@Test
public void testAddDoc() throws IOException {
//准备json数据
Map jsonMap = new HashMap<>();
jsonMap.put("name", "spring cloud实战");
jsonMap.put("description", "本课程主要从四个章节进行讲解: 1.微服务架构入门 2.spring cloud 基础入门 3.实战Spring Boot 4.注册中心eureka。");
jsonMap.put("studymodel", "201001");
SimpleDateFormat dateFormat =new SimpleDateFormat("yyyy‐MM‐dd HH:mm:ss");
jsonMap.put("timestamp", dateFormat.format(new Date()));
jsonMap.put("price", 5.6f);
//索引请求对象
IndexRequest indexRequest = new IndexRequest("xc_course","doc");
//指定索引文档内容
indexRequest.source(jsonMap);
//索引响应对象
IndexResponse indexResponse = restHighLevelClient.index(indexRequest);
//获取响应内容
DocWriteResponse.Result result = indexResponse.getResult();
System.out.println(result);
}
3.2查询文档
@Test
public void testGetDoc() throws IOException {
//查询请求对象
GetRequest getRequest=new GetRequest("xc_course","doc","lJpazGsBtkIcW-SjsCSK");
GetResponse getResponse = restHighLevelClient.get(getRequest);
//得到文档的内容
Map map = getResponse.getSourceAsMap();
System.out.println(map);
}
3.3更新文档
@Test
public void testUpdateDoc() throws IOException {
//更新请求对象
UpdateRequest updateRequest=new UpdateRequest("xc_course","doc","lJpazGsBtkIcW-SjsCSK");
//准备需要更新的数据
Map jsonMap=new HashMap<>();
jsonMap.put("name","林师妹");
//指定doc
updateRequest.doc(jsonMap);
//执行更新
UpdateResponse updateResponse = restHighLevelClient.update(updateRequest);
//获取响应
RestStatus status = updateResponse.status();
System.out.println(status);
}
3.4删除文档
@Test
public void testDeleteDoc() throws IOException {
//删除请求对象
DeleteRequest deleteRequest=new DeleteRequest("xc_course","doc","lJpazGsBtkIcW-SjsCSK");
//执行删除
DeleteResponse deleteResponse = restHighLevelClient.delete(deleteRequest);
//获取响应结果
DocWriteResponse.Result result = deleteResponse.getResult();
System.out.println(result);
}
四:搜索管理
4.1搜索全部
@Test
public void testSearchAll() throws IOException{
//搜索请求对象
SearchRequest searchRequest=new SearchRequest("xc_course");
//设置搜索类型
searchRequest.types("doc");
//搜索源构建对象
SearchSourceBuilder searchSourceBuilder=new SearchSourceBuilder();
//搜索方式 -- 搜索全部
searchSourceBuilder.query(QueryBuilders.matchAllQuery());
//设置过滤的字段 第一部分为需要的字段 第二部分为不需要的字段
searchSourceBuilder.fetchSource(new String[]{"name","studymodel","price","description","timestamp"},new String[]{});
//搜索对象中设置搜索源
searchRequest.source(searchSourceBuilder);
//客户端发送http请求
SearchResponse searchResponse = restHighLevelClient.search(searchRequest);
//获取查询结果
SearchHits hits = searchResponse.getHits();
SearchHit[] searchHits = hits.getHits();
for (SearchHit hit:searchHits){
Map sourceAsMap = hit.getSourceAsMap();
String name = (String) sourceAsMap.get("name");
Double price= (Double) sourceAsMap.get("price");
String description = (String) sourceAsMap.get("description");
String time = (String) sourceAsMap.get("timestamp");
System.out.println(name+"\n"+price+"\n"+description+"\n"+time+"\n");
}
4.2分页搜索
- 在4.1的代码中添加如下代码即可
//设置分页参数
//页码
int page=1;
//每页记录数
int size=2;
//计算每页起始下标
int from=(page-1)*size;
searchSourceBuilder.from(from);
searchSourceBuilder.size(size);
4.3TermQuery
- 注意
termQuery为精确查询,在搜索时会整体匹配关键字,不再将关键字分词。
- 将4.1中搜索方式代码修改成如下即可
//设置搜索方式 TermQuery
searchSourceBuilder.query(QueryBuilders.termQuery("name","spring"));
4.4根据id精确查询
- 注意
使用id查询时 代码应为termsQuery 4.3则为termQuery
- 将4.1中搜索方式代码修改成如下即可
//主键
String[] ids=new String[]{"1","2"};
//设置搜索方式 TermsQuery
searchSourceBuilder.query(QueryBuilders.termsQuery("_id",ids));
4.5MatchQuery
match Query即全文检索,它的搜索方式是先将搜索字符串分词,再使用各各词条从索引中搜索。 match query与Term query区别是match query在搜索前先将搜索关键字分词,再拿各各词语去索引中搜索。
- minimumShouldMatch
//设置搜索方式 matchQuery 3个关键字 3*0.7=2.1 取整搜索出现两个的记录
searchSourceBuilder.query(QueryBuilders.matchQuery("description","spring开发框架").minimumShouldMatch("70%"));
- operator
//设置搜索方式 matchQuery or表示有其中一个就可以 and表示全部关键字都需要
searchSourceBuilder.query(QueryBuilders.matchQuery("description","spring开发框架").operator(Operator.OR));
4.6MultiMatchQuery
上边学习的TermQuery和MatchQuery一次只能匹配一个Field
单项匹配是在一个field中去匹配,多项匹配是拿关键字去多个Field中匹配
- 使用此方法 关键字中间必须需要空格 10是boost分数 表示×10倍
- 此方法在实际开发中使用较多
//设置搜索方式 multiMatchQuery
searchSourceBuilder.query(QueryBuilders.multiMatchQuery("spring css","name","description")
.minimumShouldMatch("50%").field("name",10));
4.7布尔查询
布尔查询对应于Lucene的BooleanQuery查询,实现将多个查询组合起来。
- must:文档必须匹配must所包括的查询条件,相当于 “AND”
- should:文档应该匹配should所包括的查询条件其 中的一个或多个,相当于 "OR"
- must_not:文档不能匹配must_not所包括的该查询条件,相当于“NOT”
//设置搜索方式 multiMatchQuery
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring css", "name", "description")
.minimumShouldMatch("50%").field("name", 10);
//设置搜索方式 matchQuery
MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("studymodel", "201001");
//定义BoolQuery
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
boolQueryBuilder.must(multiMatchQueryBuilder);
boolQueryBuilder.must(matchQueryBuilder);
searchSourceBuilder.query(boolQueryBuilder);
4.8过滤器
过滤是针对搜索的结果进行过滤,过滤器主要判断的是文档是否匹配,不去计算和判断文档的匹配度得分,所以过滤器性能比查询要高,且方便缓存,推荐尽量使用过滤器去实现查询或者过滤器和查询共同使用。过滤器在布尔查询中使用,下边是在搜索结果的基础上进行过滤:
- 过滤出studymodel 为201001
- 过滤出price区间为60-100
//设置搜索方式 multiMatchQuery
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring css", "name", "description")
.minimumShouldMatch("50%").field("name", 10);
//定义BoolQuery
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
boolQueryBuilder.must(multiMatchQueryBuilder);
//定义过滤器
boolQueryBuilder.filter(QueryBuilders.termQuery("studymodel","201001"));
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(60).lte(100));
searchSourceBuilder.query(boolQueryBuilder);
4.9排序
可以在字段上添加一个或多个排序,支持在keyword、date、float等类型上添加,text类型的字段上不允许添加排序。
//定义BoolQuery
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
//定义过滤器
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100));
searchSourceBuilder.query(boolQueryBuilder);
//设置排序 按照降序
searchSourceBuilder.sort("studymodel", SortOrder.DESC);
4.10高亮显示
高亮显示可以将搜索结果一个或多个字突出显示,以便向用户展示匹配关键字的位置。
- 搜索方式
//设置搜索方式 multiMatchQuery
MultiMatchQueryBuilder multiMatchQueryBuilder = QueryBuilders.multiMatchQuery("spring css", "name", "description")
.minimumShouldMatch("50%").field("name", 10);
//定义BoolQuery
BoolQueryBuilder boolQueryBuilder=new BoolQueryBuilder();
boolQueryBuilder.must(multiMatchQueryBuilder);
//定义过滤器
boolQueryBuilder.filter(QueryBuilders.termQuery("studymodel","201001"));
boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(0).lte(100));
searchSourceBuilder.query(boolQueryBuilder);
- 高亮的设置
//设置高亮
HighlightBuilder highlightBuilder=new HighlightBuilder();
//设置前缀
highlightBuilder.preTags("");
//设置后缀
highlightBuilder.postTags("");
//设置高亮字段
highlightBuilder.fields().add(new HighlightBuilder.Field("name"));
searchSourceBuilder.highlighter(highlightBuilder);
- 取值
String name = (String) sourceAsMap.get("name");
//取出name高亮
Map highlightFields = hit.getHighlightFields();
if (highlightFields!=null){
HighlightField highlightField = highlightFields.get("name");
if (highlightField!=null){
Text[] fragments = highlightField.getFragments();
StringBuffer stringBuffer=new StringBuffer();
for (Text text:fragments){
stringBuffer.append(text);
}
name=stringBuffer.toString();
}
}
Comments | NOTHING