倒排索引、分词、同义词

倒排索引

  • 正排索引:文档ID =>文档内容和单词
  • 倒排索引:词条 =>文档ID
  • 倒排索引组成:
    • 词条字典(Term Dictionary),记录所有的词条与倒排列表的映射关系。这个字典很大,通过B+树或哈希拉链法实现,以满足高性能的插入与查询。
    • 倒排列表(Posting List),由倒排索引项组成,包含如下信息:
      • 文档ID
      • 词频(TF):该单词在文档中出现的次数,用于相关性评分
      • 位置(Position):单词在文档中分词的位置(也就是第几个分词),用于语句搜索(phrase query)
      • 偏移(Offset):记录单词的开始结束位置,实现高亮显示(从第几个字符开始,到第几个字符结束)
  • ES的倒排索引:
    • ES文档的每个字段,默认都有自己的倒排索引
    • 可以通过mappings,指定某些字段不做索引,以节省存储空间,但会导致该字段无法被搜索。

分词

文本分析(Analysis),就是把全文转换成一系列词条(term / token)的过程(也叫分词)。文本分析是通过分词器(Analyzer)实现的。

https://www.elastic.co/guide/en/elasticsearch/reference/7.2/analysis.html

分词器有两个作用:

  • 数据写入时转换词条
  • 分析查询语句

ES内置了多种分词器:https://www.elastic.co/guide/en/elasticsearch/reference/7.2/analysis-analyzers.html

在mapping中,每个text字段都可以指定专门的分词器:

PUT {
   index}  
{
   
  "mappings": {
   
    "properties": {
   
      "{field}": {
   
        "type": "text",
        "analyzer": "{standard}"  // 指定分词器
      }
    }
  }
}

说明:已经存在的索引执行上述操作会报错。可以在创建索引时指定。standard分词器是默认的分词器。

通常情况下,创建(index)和查询(search)时,应该使用同样的分词器。执行全文检索时,比如match查询,会在mapping中为每个字段查找分词器。在查询具体字段时使用何种分词器,遵循如下查找顺序:

  • 查询条件有指定analyzer
  • mapping中的search_anylyzer参数
  • mapping中的analyzer参数
  • 索引设置中的default_search
  • 索引设置中的default
  • standard分词器

分词器由以下三部分组合而成:

  • Character Filters:处理原始文本,比如去除html标签。一个分词器可以没有或拥有多个char filter。

  • Tokenizer:接收上一步处理后的文本流,按照规则切分出词条并输出,比如:

    • whitespace 按空格切分词条
    • keyword 不做分词,直接作为关键词
    • path_hierarchy, 按路径切分,保证搜索任意一级目录都可以搜索到结果

    更多类别参考官网,每个分词器必须有一个tokenizer。

  • Token Filters:接收词条流,进行再加工,可能会添加、删除、或者变更词条。比如:

    • lowercase 将所有的词条转为小写
    • stop将停顿词(比如,the, in, on)从词条流中移除
    • synonym往词条流中引入同义词
    • multiplexer 一个单词触发多个词条(应用多个过滤器,每个过滤器触发一个),重复的词条会被去除。建议:将同义词过滤器追加到每个multiplexer过滤器列表后面,不要放在multiplexer之后,以避免异常。建议具体见官网底部的note

    更过token filter类别可以参考官网,一个分词器可以没有或拥有多个token filter

通过组合以上三部分,我们也可以自定义分词器。

###analyze接口

analyze接口可以用来执行文本分析处理,并查看分词结果,比如:

GET _analyze
{
   
  "analyzer": "standard",
  "text": "hello world"
}

使用standard分词器对文本进行分词,返回结果如下:

{
   
  "tokens" : [
    {
   
      "token" : "hello",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
   
      "token" : "world",
      "start_offset" : 6,
      "end_offset" : 11,
      "type" : "<ALPHANUM>",
      "position" : 1
    }
  ]
}

自定义分词

也可以自己定义分词器,其实就是组合tokenizer, token filter 和 char filer,比如:

示例1:自定义token filter

POST _analyze
{
   
  "tokenizer": "standard",
  "filter":  [ "lowercase", "asciifolding" ],
  "text":      "Is this déja vu?"
}

示例2:自定义char_filter

POST _analyze
{
   
  "tokenizer": "standard",
  "char_filter": [
    {
   
      "type": "mapping",
      "mappings": ["- => _"]  // 将中划线替换为下划线, 甚至可以将emoji表情替换为单词
    }
    ],
    "text": "123-456, hello-world"
}

// 结果如下:
{
   
  "tokens" : [
    {
   
      "token" : "123_456",
      "start_offset" : 0,
      "end_offset" : 7,
      "type" : "<NUM>",
      "position" : 0
    },
    {
   
      "token" : "hello_world",
      "start_offset" : 9,
      "end_offset" : 20,
      "type" : "<ALPHANUM>",
      "position" : 1
    }
  ]
}

也可以为某个索引(集)自定义分词器:

put forum
{
   
  "settings": {
   
    "analysis
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值