Elasticsearch实现复合查询高亮结果功能

2022-10-16,,,,

一.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实现复合查询高亮结果功能,希望对大家有所帮助

《Elasticsearch实现复合查询高亮结果功能.doc》

下载本文的Word格式文档,以方便收藏与打印。