一.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实现复合查询高亮结果功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对小牛知识库网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!
本文向大家介绍JavaScript实现关键字高亮功能,包括了JavaScript实现关键字高亮功能的使用技巧和注意事项,需要的朋友参考一下 高亮功能主要是指对页面中指定区域的指定文字进行高亮显示,也就是背景着色。一般在搜索结果页面会经常用到这个功能。 下面就为大家提供一种解决方案,用javascript实现。 首先在<head>中引入下面javascript方法: 上面的fHl方法就是用来实现高亮
问题内容: 我目前正在使用Elasticsearch在查询中提供的突出显示功能。但是,我不太清楚的一件事是关于结果的排序方式。我希望他们在段落而不是重要性/得分中返回。这样一来,我就可以按照与原始文档中相同的顺序将它们与连接在一起(类似于Google结果)。但是,他们目前正在根据最佳匹配以某种加权顺序返回? 有没有一种方法可以完成此操作,而无需在看到突出显示结果之后在现场进行其他后处理。 我看到有
问题内容: 我正在使用ElasticSearch索引文档。 我的映射是: 为了突出显示全文,我将其设置为0。 如果我执行以下类似于Lucene的字符串查询: 对于结果集中的某些文档,突出显示的全文的长度小于全文本身的长度。由于我将值设置为0和/ ,所以不会发生这种情况。 现在出现奇怪的行为:如果我仅通过执行以下操作搜索失败的元素之一: 然后一切正常。 有任何想法吗? 问题答案: 听起来像在0.14
本文向大家介绍Vue实现搜索结果高亮显示关键字,包括了Vue实现搜索结果高亮显示关键字的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Vue实现搜索结果高亮显示关键字的具体代码,供大家参考,具体内容如下 1. 需要解决的问题 父组件将搜索的字段传到子组件 子组件接受数据,正则匹配,并替换字段 2. 具体代码 父组件代码 子组件代码 以上就是本文的全部内容,希望对大家的学习有所帮助,也
问题内容: 当我将分析器与Edgengram(最小= 3,最大= 7,前面)+ term_vector = with_positions_offsets一起使用时 使用具有text =“ CouchDB”的文档 当我搜索“ couc”时 我的重点是“ cou”而不是“ couc” 看来我的重点只是在最小匹配令牌“ cou”上,而我希望是在精确令牌(如果可能)上或至少在找到的最长令牌上。 无需使用t
我在sqlite查询结果的子查询中遇到问题。当执行下面的查询时,成功返回Sqlite数据库中的结果,但当运行程序时,它不返回任何值。我在下面的程序中做错了什么。请给我一些建议。 查询: java程序: