参考文档《集成Elasticsearch Restful API案例》导入和配置es客户端
通过组件DocumentCRUD 来创建索引表和初始化数据,DocumentCRUD 组件实现本文不做重点介绍:
/**
* 创建索引表,并导入高亮检索功能需要的测试数据
*/
public void initIndiceAndData(){
DocumentCRUD documentCRUD = new DocumentCRUD();
documentCRUD.testCreateIndice();
documentCRUD.testBulkAddDocuments();
}
在文件esmapper/demo.xml中增加testHighlightSearch配置:
dsl中变量语法参考文档:开发指南
<!--
一个简单的检索dsl,中有四个变量
name 全文检索字段
startTime
endTime
通过map传递变量参数值
-->
<property name="testHighlightSearch">
<![CDATA[{
"query": {
"bool": {
"filter": [
{ ## 时间范围检索,返回对应时间范围内的记录,接受long型的值
"range": {
"agentStarttime": {
"gte": #[startTime],##统计开始时间
"lt": #[endTime] ##统计截止时间
}
}
}
],
"must": [
#*
{
"query_string": {
"query": #[condition],
"analyze_wildcard": true
}
}
*#
{
## 全文检索参考文档 https://www.elastic.co/guide/en/elasticsearch/reference/6.2/full-text-queries.html
"match_phrase" : {
"name" : {
"query" : #[condition]
}
}
}
]
}
},
## 最多返回1000条记录
"size":1000,
## 高亮检索定义,参考文档:https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search-request-highlighting.html
"highlight": {
"pre_tags": [
"<mark>"
],
"post_tags": [
"</mark>"
],
"fields": {
"*": {}
},
"fragment_size": 2147483647
}
}]]>
</property>
创建检索类-org.bboss.elasticsearchtest.HighlightSearch
在其中定义以下方法
public void highlightSearch() throws ParseException {
//创建加载配置文件的客户端工具,用来检索文档,单实例多线程安全
ClientInterface clientUtil = ElasticSearchHelper.getConfigRestClientUtil(mappath);
//设定查询条件,通过map传递变量参数值,key对于dsl中的变量名称
//dsl中有三个变量
// condition
// startTime
// endTime
Map<String,Object> params = new HashMap<String,Object>();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//设置时间范围,时间参数接受long值
params.put("startTime",dateFormat.parse("2017-09-02 00:00:00"));
params.put("endTime",new Date());
params.put("condition","喜欢唱歌");//全文检索条件,匹配上的记录的字段值对应的匹配内容都会被高亮显示
//执行查询,demo为索引表,_search为检索操作action
ESDatas<Demo> esDatas = //ESDatas包含当前检索的记录集合,最多1000条记录,由dsl中的size属性指定
clientUtil.searchList("demo/_search",//demo为索引表,_search为检索操作action
"testHighlightSearch",//esmapper/demo.xml中定义的dsl语句
params,//变量参数
Demo.class);//返回的文档封装对象类型
//获取总记录数
long totalSize = esDatas.getTotalSize();
System.out.println(totalSize);
//获取结果对象列表,最多返回1000条记录
List<Demo> demos = esDatas.getDatas();
for(int i = 0; demos != null && i < demos.size(); i ++){//遍历检索结果列表
Demo demo = demos.get(i);
//记录中匹配上检索条件的所有字段的高亮内容
Map<String,List<Object>> highLights = demo.getHighlight();
Iterator<Map.Entry<String, List<Object>>> entries = highLights.entrySet().iterator();
while(entries.hasNext()){
Map.Entry<String, List<Object>> entry = entries.next();
String fieldName = entry.getKey();
System.out.print(fieldName+":");
List<Object> fieldHighLightSegments = entry.getValue();
for (Object highLightSegment:fieldHighLightSegments){
/**
* 在dsl中通过<mark></mark>来标识需要高亮显示的内容,然后传到web ui前端的时候,通过为mark元素添加css样式来设置高亮的颜色背景样式
* 例如:
* <style type="text/css">
* .mark,mark{background-color:#f39c12;padding:.2em}
* </style>
*/
System.out.println(highLightSegment);
}
}
}
}
高亮检索返回的索引字段高亮关键字信息被封装以Map<String,List>类型包含在每条索引文档中返回,bboss支持三种方式存放索引字段高亮关键字信息
方式一 结果对象继承ESBaseData
结果对象可以继承ESBaseData抽象类,字段高亮关键字信息将被自动设置到父类ESBaseData的属性:
Map<String,List<Object>> highlight;
例如:本案例中的Demo对象
public class Demo extends ESBaseData {
。。。。。。。
}
方式二 使用@ESMetaHighlight注解
在对象中定义带@ESMetaHighlight注解类型为Map<String,List>的字段,例如:
public class Demo {
@ESMetaHighlight //文档对应的高亮检索信息
Map<String,List<Object>> highlights;
。。。。。。。
}
方式 二优于方式一,不需为了高亮信息在对象中引入其他的元数据字段,同时也可以按照自己的要求命名高亮字段的名称,避免命名冲突
跟多元数据信息,可以参考文档:
方式三 使用MetaMap
如果我们既要使用Map对象来封装文档数据,又想返回高亮检索信息,那么可以使用MetaMap类型来替代Map类型,例如:
//设定查询条件,通过map传递变量参数值,key对于dsl中的变量名称
//dsl中有三个变量
// condition
// startTime
// endTime
Map<String,Object> params = new HashMap<String,Object>();
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//设置时间范围,时间参数接受long值
params.put("startTime",dateFormat.parse("2017-09-02 00:00:00"));
params.put("endTime",new Date());
params.put("condition","喜欢唱歌");//全文检索条件,匹配上的记录的字段值对应的匹配内容都会被高亮显示
//列表检索
ESDatas<MetaMap> data //ESDatas为查询结果集对象,封装了返回的当前查询的List<MetaMap>结果集和符合条件的总记录数totalSize
= clientUtil.searchList("demo/_search",//demo为索引表,_search为检索操作action
"testHighlightSearch",//通过名称引用配置文件中的query dsl语句
parmas,//查询条件,Map<key,value>
MetaMap.class);//指定返回对象类型为MetaMap
//获取结果对象列表
List<MetaMap> demos = data.getDatas();
//获取总记录数
long totalSize = data.getTotalSize();
//遍历列表,并从MetaMap中获取检索元数据
for(int i = 0; demos != null && i < demos.size(); i ++){
//单文档检索
MetaMap newDemo = demos.get(i);
//打印metamap文档高亮信息
System.out.println("getHighlight:"+newDemo.getHighlight());//高亮信息
。。。。
}
metamap的使用可以参考文档:
定义junit测试用例:
import org.junit.Test;
import java.text.ParseException;
public class HighlightSearchTest {
@Test
public void testHighlightSearch() throws ParseException {
HighlightSearch highlightSearch = new HighlightSearch();
highlightSearch.initIndiceAndData();
highlightSearch.highlightSearch();
}
@Test
public void testHighlightSearchOther() throws ParseException {
HighlightSearch highlightSearch = new HighlightSearch();
highlightSearch.initIndiceAndData();
highlightSearch.highlightSearchOther();
}
}
在idea或者eclipse中运行测试用例即可,输出检索到的高亮内容信息如下:
name:刘德华<mark>喜</mark><mark>欢</mark><mark>唱</mark><mark>歌</mark>454
name:刘德华<mark>喜</mark><mark>欢</mark><mark>唱</mark><mark>歌</mark>488
name:刘德华<mark>喜</mark><mark>欢</mark><mark>唱</mark><mark>歌</mark>508
name:刘德华<mark>喜</mark><mark>欢</mark><mark>唱</mark><mark>歌</mark>518
https://github.com/bbossgroups/eshelloword-booter
https://www.elastic.co/guide/en/elasticsearch/reference/6.2/search-request-highlighting.html
https://esdoc.bbossgroups.com/#/common-project-with-bboss
QQ交流群:21220580,166471282,3625720,154752521,166471103,166470856
微信交流群:
交流社区: