elasticsearch中highlight的“假匹配”

elasticsearch中highlight的“假匹配”

一个highlight的假高亮现象:

/company_meta_info/_search?rest_total_hits_as_int=true

{
  "_source": {
    "includes": ["name","address"]
  },
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "address": {
              "query": "新疆蓝天七色建材有限公司",
              "operator": "and"
            }
          }
        }
      ]
    }
  },
  "highlight": {
    "fields": {
      "name": {},
      "address": {}
    }
  },
  "from": 0,
  "size": 10
}

返回结果:可以发现通过地址是没有匹配到任何结果

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 6,
    "successful": 6,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 0,
    "max_score": null,
    "hits": []
  }
}

换一种方式:先设法把文档召回

{
  "_source": {
    "includes": ["name","address"]
  },
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "address": {
              "query": "新疆蓝天七色建材有限公司",
              "operator": "and"
            }
          }
        },
        {
          "match": {
            "org_id": "Q0000D2AC1" //此处匹配目标
          }
        }
      ]
    }
  },
  "highlight": {
    "fields": {
      "name": {},
      "address": {}
    }
  },
  "from": 0,
  "size": 10
}

返回结果:可以发现,结果并不是由于address字段命中召回的,但是highlight却有address,so 这是为什么尼

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 6,
    "successful": 6,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 8.805375,
    "hits": [
      {
        "_index": "company_meta_info_v6",
        "_type": "_doc",
        "_id": "Q0000D2AC1",
        "_score": 8.805375,
        "_source": {
          "address": "新疆五家渠市北一东街1299号",
          "name": "新疆蓝天七色建材有限公司"
        },
        "highlight": {
          "address": [
            "新疆五家渠市北一东街1299号"
          ]
        }
      }
    ]
  }
}

这就需要了解elasticsearch中的高亮处理方式了。在elasticsearch中有三种高亮处理方式:highlighter, fast-vector-highlighter, postings-highlighter。默认使用的是highlighter方式。

highlighter 高亮也叫plain高亮,highlighter方式高亮是个实时分析处理高亮器。即用户在查询的时候,搜索引擎查询到了目标数据后,将需要高亮的字段数据提取到内存,再调用该字段的分析器进行处理,分析器对文本进行分析处理,分析完成后采用相似度算法计算得分最高的前n组并高亮段返回数据。

fast-vector-highlighter(fvh)高亮器利用建索引时候保存好的词项向量(term vector)来直接计算高亮段落,在高亮过程中比plain高亮方式少了实时分析过程,取而代之的是直接从磁盘中将分词结果直接读取到内存中进行计算。故要使用fvh的前置条件就是在建索引时候,需要配置存储词项向量,词向量需要包含词位置信息、词偏移量信息。

配置选项 描述
no 不启用term vector,默认值
yes 启用term vector,但是仅仅记录分词
with_positions 启用term vector, 记录分词及分词在字符串中的位置
with_offsets 启用term vector, 记录分词在字符串中的起始字符位置
with_positions_offsets 启用term vector, 记录分词在字符串中的位置及起始的字符位置
with_positions_payloads 启用term vector, 记录分词在字符串中的位置及payloads
with_positions_offsets_payloads 启用term vector, 记录分词在字符串中的位置、起始字符位置及payloads

fvh在高亮时候的逻辑如下:

1.分析高亮查询语法,提取表达式中的高亮词集合
2.从磁盘上读取该文档字段下的词向量集合
3.遍历词向量集合,提取自表达式中出现的词向量
4.根据提取到目标词向量读取词频信息,根据词频获取每个位置信息、偏移量
5.通过相似度算法获取得分较高的前n组高亮信息
6.读取字段内容(多字段用空格隔开),根据提取的词向量直接定位截取高亮字段

postings-highlighter(postings)。postings 高亮方式与fvh相似,采用词量向量的方式进行高亮,与fvh高亮不同的是postings高亮只存储了词向量的位置信息,并未存储词向量的偏移量,故中大字段存储中,postings其比fvh节省约20-30%的存储空间,速度与fvh基本相当。

so 由上述的表述我们就知道了,plain类型高亮方式,是首先召回文档,然后对文档进行高亮处理,在高亮处理的过程中并不会参考我们query中的配置条件(“operator”: “and”);所以才会出现我们上面例子中的现象。单靠address条件并不会召回目标文档;当我们用其他条件召回了目标文档时,会进行高亮处理。

我们并不能单纯的将highlight的结果当成文档的匹配原由,想要了解匹配原理还是要通过explain

你可能感兴趣的:(elasticsearch)