一、highlight简介

highlight是提升用户体验的重要手段,搜索引擎通过高亮突出命中关键字等方式,方便用户通过关键字周围的信息快速的确认是否是自己希望的结果;

highlight功能通常包含以下三个主要的处理过程

1.将字段文本拆分为小的片段;

2.找出最相关的片段;

3.高亮查询关键字;

二、elasticsearch的highlight功能

elasticsearch提供了专门的高亮请求参数highlight,返回的记过中也会包含对应的高亮信息;

在查询语句中,我们要求对text字段进行高亮处理;

GET /twitter/_search
{
"query": {
"match": {
"text": "Another"
}
},
"highlight": {
"fields": {
"text": {}
}
}
}

elasticsearch默认使用em对命中关键字进行包裹处理;

{
"took" : 1,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : 1,
"max_score" : 0.6931472,
"hits" : [
{
"_index" : "twitter",
"_type" : "_doc",
"_id" : "2",
"_score" : 0.6931472,
"_source" : {
"fullname" : "Jane Doe",
"text" : "Another twitter test ..."
},
"highlight" : {
"text" : [
"<em>Another</em> twitter test ..."
]
}
}
]
}
}

高亮处理需要使用原始的字段值文本,所以elasticsearch需要保存字段的值,我们可以在字段的mapping中设置store为true,否则只能从_source字段中load对应字段值;

三、elasticsearch提供的三种highlighter

elasticsearch提供了以下三种highlighter

Unified highlighter

这个unified highlighter是elasticsearch的默认highlighter,其使用的是Lucene Unified Highlighter,它会将文本分割为句子片段,然后使用BM25算法计算每个句子片段的相似性得分;改highlighter支持phrase、fuzzy、prefix等查询的高亮处理;

Plain highlighter

这个plain Highlighter使用的是标准的lucene Highlighter,其通过关键字的重要性及关键字的位置信息,尝试尽量的体现查询的匹配逻辑;

为了更加准确的体现查询的逻辑,Plain Highlighter需要针对具体的查询和命中文档的每个字段进行实时的计算,其会在内存中创建一个小型的index,然后通过查询计划重新执行一遍查询,从而获得高亮需要使用底层的匹配信息,所以其比较适合小型的字段;

Fast vector highlighter

这个fvh Highlighter使用的是Lucene Fast Vector Highlighter,其基于term_vector的数据结构,需要在mapping中将相应的字段设置为with_positions_offsets;其比较适合对大文本字段进行高亮处理;

四、Highlighter的高亮处理过程

Highlighter的主要工作就是通过传入的查询和命中的文档,找到能够最好反应匹配相关性的高亮片段;其主要需要完成以下三个工作;

1.将文本查分为小的高亮片段

本阶段主要将字段值文本拆分为小的高亮片段,三种Highlighter的处理过程如下

Plain Highlighter首先使用字段对应的analyzer对文本进行分词处理,然后通过得到的每个分词的起止字符位置,依次截取fragment_size的文本段;由于根据固定的片段长度拆分,得到的片段效果往往很不理想;

Unified和fvh Highlighter都通过Java的BreakIterator进行拆分高亮片段,配合fragment_size可以得到比较完整的句子;

2.找到最相关的高亮片段;

本阶段主要通过实际命中记录的查询关键字,对得到的高亮片段进行打分,从而找到跟查询最相关的高亮片段;

要计算高亮片段的匹配情况,有两种主要的方式

  1. 高亮处理的时候实时计算匹配情况,这样就需要针对每个高亮片段创建临时索引,并执行查询语句来获取匹配信息;
  2. index的时候进行相关分词起止字符的统计信息处理和保存;
  • postings list,在字段mapping的时候,可以通过index_options来控制记录到倒排索引中的分词统计信息,通过设置offsets可以保存记录分词的起止信息;
  • term vector,elasticsearch提供的term_vector也记录了分词过程中产生的分词的起止信息,也是在字段mapping的时候进行设置,需要设置为with_positions_offsets;

三种Highlighter的处理过程如下

Plain Highlighter首先会利用高亮片段生成的分词在内存中创建一个index,并通过lucene查询计划执行原始的查询,然后通过命中信息获得匹配的分词,通过计算高亮片段的包含的不同查询分词的数量计算相关性得分;这里直接使用查询分词的boost(默认值)进行计算;

fvh Highlighter直接利用index的时候创建的term vector来得到高亮片段匹配的查询分词,其对高亮片段的评分算法跟Plain Highlighter类似,只不过这里会将命中的所有查询分词(包括重复的查询分词)计算在内;

unified Highlighter会尝试优先使用term vectors,index中的postings list,否则只能跟plain Highlighter相同的方式进行实时计算;其使用BM25算法计算高亮片段的相似度;

3.Highlight高亮片段;

本阶段主要进行输出前的编码和格式化,最后使用pre-tags、post-tags来包裹高亮片段中的查询关键字;

elasticsearch高亮之highlight原理的更多相关文章

  1. ElasticSearch之 控制相关度原理讲解

    控制相关度 相关度评分背后的理论 如何计算评分的 Lucene 使用布尔模型(Boolean model) 查找匹配文档 并主要的借鉴了 词频/逆向文档频率(term frequency/invers ...

  2. 代码语法高亮踩坑-原理,问题, PRE元素及htmlentity

    语法高亮库基础原理 在研究使用能够在web页面上代码语法高显的解决方案时,发现有很多现成的开源库.比较中意的有prism.js,highlightjs.他们的原理基本上核心就两点: 1. 利用html ...

  3. Elasticsearch 技术分析(九):Elasticsearch的使用和原理总结

    前言 之前已经分享过Elasticsearch的使用和原理的知识,由于近期在公司内部做了一次内部分享,所以本篇主要是基于之前的博文的一个总结,希望通过这篇文章能让读者大致了解Elasticsearch ...

  4. JavaScript语法高亮库highlight.js使用

    highlight.js是一款基于JavaScript的语法高亮库,目前支持125种编程语言,有63种可供选择的样式,而且能够做到语言自动识别,和目前主流的JS框架都能兼容,可以混合使用. 这款高亮库 ...

  5. Elasticsearch Lucene 数据写入原理 | ES 核心篇

    前言 最近 TL 分享了下 <Elasticsearch基础整理>https://www.jianshu.com/p/e8226138485d ,蹭着这个机会.写个小文巩固下,本文主要讲 ...

  6. Elasticsearch系列---增量更新原理及优势

    概要 本篇主要介绍增量更新(partial update,也叫局部更新)的核心原理,介绍6.3.1版本的Elasticsearch脚本使用实例和增量更新的优势. 增量更新过程与原理 简单回顾 前文我们 ...

  7. Elasticsearch系列---shard内部原理

    概要 本篇我们来看看shard内部的一些操作原理,了解一下人家是怎么玩的. 倒排索引 倒排索引的结构,是非常适合用来做搜索的,Elasticsearch会为索引的每个index为analyzed的字段 ...

  8. Elasticsearch系列---聚合查询原理

    概要 本篇主要介绍聚合查询的内部原理,正排索引是如何建立的和优化的,fielddata的使用,最后简单介绍了聚合分析时如何选用深度优先和广度优先. 正排索引 聚合查询的内部原理是什么,Elastich ...

  9. Elasticsearch 分片集群原理、搭建、与SpringBoot整合

    单机es可以用,没毛病,但是有一点我们需要去注意,就是高可用是需要关注的,一般我们可以把es搭建成集群,2台以上就能成为es集群了.集群不仅可以实现高可用,也能实现海量数据存储的横向扩展. 新的阅读体 ...

随机推荐

  1. c语言字符串函数详解

    转载请注明来源:https://www.cnblogs.com/hookjc/ oid *memset(void *dest, int c, size_t count); 将dest前面count个字 ...

  2. Java线程--CopyOnWrite容器使用

    原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11871602.html Java线程--CopyOnWrite容器使用 CopyOnWrit容 ...

  3. 在ABP VNext框架中处理和用户相关的多对多的关系

    前面介绍了一些ABP VNext架构上的内容,随着内容的细化,我们会发现ABP VNext框架中的Entity Framework处理表之间的引用关系还是比较麻烦的,一不小心就容易出错了,本篇随笔介绍 ...

  4. UVM宏

    1.注册宏 // 注册object类 `uvm_object_utils(类名) `uvm_object_parm_utils(类名) `uvm_object_utils_begin(类名) // 注 ...

  5. JAVA8学习——新的时间日期API&Java8总结

    JAVA8-时间日期API java8之前用过的时间日期类. Date Calendar SimpleDateFormat 有很多致命的问题. 1.没有时区概念 2.计算麻烦,实现困难 3.类是可变的 ...

  6. MySQL是怎么保证redo log和binlog是完整的?

    摘要:WAL机制保证只要redo log和binlog保证持久化到磁盘,就能确保MySQL异常重启后,数据可以恢复. 本文分享自华为云社区<MySQL会丢数据吗?>,作者: JavaEdg ...

  7. ESP32-S3 arduino 开发环境搭建

    ESP32-S3 arduino 简要描述 在github上搜索arduino-esp32,找到并打开espressif/arduino-esp32仓库,从master主分支切换到esp32-s3-s ...

  8. Python 中线程和进程

    目录 线程和进程 一. 什么是进程 / 线程 1. 引论 2. 线程 3. 进程 4. 区别 5. 使用 二. 多线程使用 1. 常用方法 2. 常用参数 3. 多线程的应用 3.1 重写线程法 3. ...

  9. LED调颜色小程序

    燧星科技有一个免费的LED调颜色蓝牙小程序,小程序有一个拾色器用来调节颜色.亮度.饱和度,同时显示出RGB的十六进制与十进制数据.还有连接蓝牙模块的功能,可向通用蓝牙模块发送调节后的RGB数据,可为平 ...

  10. smbms项目核心功能实现

    SMBMS 数据库: 项目如何搭建? 考虑使用不使用Maven?依赖,Jar 1.项目搭建准备工作 搭建一个maven web项目 配置Tomcat 测试项目是否能够跑起来 导入项目中会遇到的jar包 ...