Elasticsearch实现复合查询高亮结果功能
程序员文章站
2022-05-25 10:56:58
一.es的配置
实现es的全文检索功能的第一步,首先从与es进行连接开始,这里我使用的是es的5.x java api语法.
public transportc...
一.es的配置
实现es的全文检索功能的第一步,首先从与es进行连接开始,这里我使用的是es的5.x java api语法.
public transportclient esclient() throws unknownhostexception{ settings settings = settings.builder() .put("cluster.name", "my-application") //节点的名字 .put("client.transport.sniff", true) .build(); inetsockettransportaddress iaddress = new inetsockettransportaddress( //连接es的ip地址和端口号 inetaddress.getbyname("127.0.0.1"),9300 ); //根据先前的配置生成client,后面的操作基本都是基于这个 transportclient client = new prebuilttransportclient(settings) .addtransportaddress(iaddress); return client; }
二.功能的实现
以下是全文检索的核心代码,包括我遇到的错误以及解决,包括如何对高亮失效,高亮不全等的解决.
1.查询条件
transportclient esclient = esclient(); //获取先前生成的client boolquerybuilder boolquery = querybuilders.boolquery(); //生成复合查询构造器 boolquery.mustnot( querybuilders.matchquery("",) //字段必须不包含啥 ); boolquery.should( querybuilders.matchquery(, ) //字段可以包含啥,相当于或者 ); boolquery.must( querybuilders.matchquery(,) //字段必须包含啥 );
2.高亮条件
//配置标题高亮显示 highlightbuilder highlightbuilder = new highlightbuilder(); //生成高亮查询器 highlightbuilder.field(title); //高亮查询字段 highlightbuilder.field(content); //高亮查询字段 highlightbuilder.requirefieldmatch(false); //如果要多个字段高亮,这项要为false highlightbuilder.pretags("<span style=\"color:red\">"); //高亮设置 highlightbuilder.posttags("</span>"); //下面这两项,如果你要高亮如文字内容等有很多字的字段,必须配置,不然会导致高亮不全,文章内容缺失等 highlightbuilder.fragmentsize(800000); //最大高亮分片数 highlightbuilder.numoffragments(0); //从第一个分片获取高亮片段
3.查询配置
// 根据字段进行排序,这里我根据时间进行倒排 fieldsortbuilder timesort = sortbuilders.fieldsort("time").order(sortorder.desc); //查询请求生成 searchrequestbuilder requestbuilder = esclient.preparesearch(indexname)//索引名字 .settypes(indextype) //索引类型 .setquery(boolquery) //配置查询条件 .addsort(new scoresortbuilder()) //根据查询相关度进行排序 .addsort(timesort) //再根据时间进行排序 .settrackscores(true) //避免分页之后相关性乱了 .highlighter(highlightbuilder) //配置高亮 .setfrom(from) //设置分页 .setsize();
4.获取查询结果对其高亮
//获取查询结果 searchresponse searchresponse = requestbuilder.get(); list<map<string, object>> course = new arraylist<>(); if(searchresponse.status() != reststatus.ok){ return course; } for(searchhit hit:searchresponse.gethits()){ //获取高亮字段 map<string, highlightfield> highlightfields = hit.gethighlightfields(); highlightfield titlefield = highlightfields.get(""); highlightfield contentfield = highlightfields.get(""); map<string, object> source = hit.getsource(); //千万记得要记得判断是不是为空,不然你匹配的第一个结果没有高亮内容,那么就会报空指针异常,这个错误一开始真的搞了很久 if(titlefield!=null){ text[] fragments = titlefield.fragments(); string name = ""; for (text text : fragments) { name+=text; } source.put("", name); //高亮字段替换掉原本的内容 } course.add(source); } esclient.close(); //用完记得关闭 return course;
三.结语
这样前端所获取结果的搜索内容将会被<span style="color:red;"></span>
所包含,比如我前端是微信小程序,所以直接获取内容进行渲染的话,就是一堆字符串,所以用的是小程序的富文本标签<rich-text>.
总结
以上所述是小编给大家介绍的elasticsearch实现复合查询高亮结果功能,希望对大家有所帮助