• es 分析器


    分析器一般用在下面两个场景中:

    • ·创建或更新文档时(合称索引时),对相应的文本字段进行分词处理;
    • ·查询文本字段时,对查询语句进行分词。

    ES中的分析器有很多种,但是所有分析器的结构都遵循三段式原则,即字符过滤器、分词器和词语过滤器。

    其中,字符过滤器可以有0个或多个,分词器必须只有一个,词语过滤器可以有0个或多个。从整体上来讲,三个部分的数据流方向为字符过滤器→分词器→分词过滤器。如图所示为一个分析器的构成示例。

     图 分析器构成示例

    对于不同的分析器,上述三部分的工作内容是不同的,为了正确匹配,如果在数据写入时指定了某个分析器,那么在匹配查询时也需要设定相同的分析器对查询语句进行分析。

    字符过滤器

    字符过滤器是分析器处理文本数据的第一道工序,它接收原始的字符流,对原始字符流中的字符进行添加、删除或者转换操作,进而改变原始的字符流。

    表 ES内置的字符过滤器

    分词器

    分词器在分析器中负责非常重要的一环工作——按照规则来切分词语

    分词器对文本进行切分后,需要保留词语与原始文本之间的对应关系,因此分词器还负责记录每个Token的位置,以及开始和结束的字符偏移量。

    表 ES内置的分词器

    分词过滤器

    分词过滤器接收分词器的处理结果,并可以将切分好的词语进行加工和修改,进而对分词结果进行规范化、统一化和优化处理。

    表 ES内置的分词过滤器

    分析器的使用

    ES提供了分析器的调用API,使用户可以方便地对比不同分析器的分析结果。另外,ES提供了一些开箱即用的内置分析器,这些分析器其实就是字符过滤器、分词器和分词过滤器的组合体,可以在索引建立时和搜索时指定使用这些分析器。当然,如果这些分析器不符合需求,用户还可以自定义分析器。

    测试分析API

    为了更好地理解分析器的运行结果,可以使用ES提供的分析API进行测试。在DSL中可以直接使用参数analyzer来指定分析器的名称进行测试,分析API的请求形式如下:

    POST /_analyze 
    { 
      "analyzer": ${analyzer_name},    //指定分析器名称 
     "text":${analyzer_text}           //待分析文本 
    }

    以下示例使用standard分析器分析一段英文:

    POST /_analyze 
    { 
     "analyzer": "standard",     //指定分析器名称为standard 
      "text": "The letter tokenizer is not configurable."  //待分析文本 
    }  

    上述文本的分析结果如下:

    { 
     "tokens" : [                   //分析器将文本切分后的分析结果 
        { 
          "token" : "the",          //将文本切分后的第一个词语 
          "start_offset" : 0,       //该词在文本中的起始偏移位置 
          "end_offset" : 3,         //该词在文本中的结束偏移位置 
          "type" : "<ALPHANUM>",    //词性 
          "position" : 0            //该词语在原文本中是第0个出现的词语 
        }, 
        { 
          "token" : "letter", 
          "start_offset" : 4, 
          "end_offset" : 10, 
          "type" : "<ALPHANUM>", 
          "position" : 1 
        }, 
        { 
          "token" : "tokenizer", 
          "start_offset" : 11, 
          "end_offset" : 20, 
          "type" : "<ALPHANUM>", 
          "position" : 2 
        }, 
        … 
      ] 
    }

    根据以上结果可以看到,standard分析器对文本进行分析时,按照空格把上面的句子进行了分词。分析API返回信息的参数说明如下:

    • ·token:文本被切分为词语后的某个词语;
    • ·start_offset:该词在文本中的起始偏移位置;
    • ·end_offset:该词在文本中的结束偏移位置;
    • ·type:词性,各个分词器的值不一样;
    • ·position:分词位置,指明该词语在原文本中是第几个出现的。

    start_offset和end_offset组合起来就是该词在原文本中占据的起始位置和结束位置。

    除了指定分析器进行请求分析外,还可以指定某个索引的字段,使用这个字段对应的分析器对目标文本进行分析。

    POST /hotel/_analyze 
    {                               //使用酒店索引的title字段对应的分析器分析文本 
      "field": "title", 
      "text": "金都嘉怡假日酒店" 
    }

    还可以在API中自定义分析器对文本进行分析

    POST /_analyze 
    { 
     "tokenizer": "standard",                   //使用standard分词器 
     "filter":["lowercase"],                    //使用Lower Case分词过滤器 
      "text": "JinDu JiaYi Holiday Hotel"       //待分析文本 
    }

    内置分析器 

    ES已经内置了一些分析器供用户使用,在默认情况下,一个索引的字段类型为text时,该字段在索引建立时和查询时的分析器是standard。standard分析器是由standard分词器、Lower Case分词过滤器和Stop Token分词过滤器构成的。注意,standard分析器没有字符过滤器。

    除了standard分析器之外,ES还提供了simple分析器、language分析器、whitespace分析器及pattern分析器等,这些分析器的功能如表所示。

    表 ES内置的分析器

     索引时使用分析器

    文本字段在索引时需要使用分析器进行分析,ES默认使用的是standard分析器。如果需要指定分析器,一种方式是在索引的settings参数中设置当前索引的所有文本字段的分析器,另一种方式是在索引的mappings参数中设置当前字段的分析器。

    以下示例在settings参数中指定在酒店索引的所有文本字段中使用simple分析器进行索引构建。

    PUT /hotel 
    { 
      "settings": { 
        "analysis": { 
          "analyzer": {               //指定所有text字段索引时使用simple分析器 
            "default": { 
              "type": "simple" 
            } 
          } 
        } 
      }, 
      "mappings": { 
        "properties": { 
         … 
        } 
      } 
    } 

    以下示例在mappings参数中指定在酒店索引的title字段中使用whitespace分析器进行索引构建。

    PUT /hotel 
    { 
      "mappings": { 
        "properties": { 
          "title": { 
            "type": "text", 
            //指定索引中的title字段索引时使用whitespace分析器 
            "analyzer": "whitespace"  
          }, 
          … 
        } 
      } 
    } 

    搜索时使用分析器

    为了搜索时更加协调,在默认情况下,ES对文本进行搜索时使用的分析器和索引时使用的分析器保持一致。当然,用户也可以在mappings参数中指定字段在搜索时使用的分析器。如下示例展示了这种用法:

    PUT /hotel 
    { 
      "mappings": { 
        "properties": { 
          "title": { 
            "type": "text", 
            "analyzer": "whitespace",            //索引时使用whitespace分析器 
            "search_analyzer": "whitespace"      //搜索时使用whitespace分析器 
          }, 
          … 
        } 
      } 
    }  

    注意,这里指定的搜索分析器和索引时的分析器是一致的,但是在大多数情况下是没有必要指定的,因为在默认情况下二者就是一致的。如果指定的搜索分析器和索引时的分析器不一致,则ES在搜索时可能出现有不符合预期的匹配情况,因此该设置在使用时需要慎重选择。

    自定义分析器

    当系统内置的分析器不满足需求时,用户可以使用自定义分析器。

    首先,需要在索引创建的DSL中定义分析器comma_analyzer,该分析器中只有一个分词组件,该分词组件使用逗号进行词语切分;然后在mappings中使用analyzer参数指定字段sup_env的分析器为定义好的comma_analyzer分析器。具体的DSL如下:

    PUT /hotel 
    { 
      "settings": { 
        "analysis": { 
          "analyzer": { 
            "comma_analyzer": {                  //自定义分析器 
              "tokenizer": "comma_tokenizer"     //使用comma_tokenizer分词器 
            } 
          }, 
          "tokenizer": {         //定义分词器 
            "comma_tokenizer": { 
              "type": "pattern", 
              "pattern": ","     //指定切分时使用的分隔符 
            } 
          } 
        } 
      }, 
      "mappings": { 
        "properties": { 
          "title": { 
            "type": "text", 
            "analyzer": "whitespace",  //设定title字段索引时使用whitespace分析器 
            //设定title字段搜索时使用whitespace分析器 
            "search_analyzer": "whitespace" 
          }, 
          "sup_env": { 
            "type": "text", 
            //设置sup_env字段使用comma_analyzer分析器 
            "analyzer": "comma_analyzer" 
          }, 
          … 
        } 
      } 
    }   

    下面向酒店索引中插入几条数据:

    POST /_bulk 
    {"index":{"_index":"hotel","_id":"001"}} 
    {"title": "金都嘉怡假日酒店","city": "北京","price": 337.00,"sup_env":"APP,H5"} 
    {"index":{"_index":"hotel","_id":"002"}} 
    {"title": "金都欣欣酒店","city": "天津","price": 200.00,"sup_env":"H5,WX"} 
    {"index":{"_index":"hotel","_id":"003"}} 
    {"title": "金都酒店","city": "北京","price": 500.00,"sup_env":"WX"}  

    当前用户的客户端为H5或App,当搜索“金都”关键词时应该构建的DSL如下:

    GET /hotel/_search 
    { 
      "query": { 
        "bool": { 
          "must": [ 
            {                      //match查询,使用whitespace分析器 
              "match": { 
                "title": "金都" 
              } 
            }, 
            {                      //match查询,使用comma_analyzer分析器 
              "match": { 
                "sup_env": "H5,APP" 
              } 
            } 
          ] 
        } 
      } 
    }  

    使用自定义的分词器可以将以逗号分隔的字段进行分词后建立索引,从而在搜索时也使用逗号分隔符进行匹配搜索。

  • 相关阅读:
    jvm误区--动态对象年龄判定
    jmeter入门实例
    七牛云的文件上传和下载
    layer.prompt添加多个输入框
    zero copy图解
    java枚举的线程安全及序列化
    java单例模式
    ubuntu16.04 python3.5 opencv的安装与卸载(转载)
    独家git clone 加速方法
    apt get update无法正常使用解决方案(转载)
  • 原文地址:https://www.cnblogs.com/ooo0/p/15672838.html
Copyright © 2020-2023  润新知