一、内置分析器
前面说过,每个被分析字段经过一系列的处理步骤:
1)字符过滤:使用字符过滤器转变字符。
2)文本切分为分词:将文本切分为单个或多个分词。
3)分词过滤:使用分词过滤器转变每个分词。
每个分析器基本上都要包含上面三个步骤至少一个。其中字符过滤器可以为0个,也可以为多个,分词器则必须,但是也只能有一个,分词过滤器可以为0个或者多个。Elasticsearch已经为我们内置了很多的字符过滤器、分词器和分词过滤器,以及分析器。不过常用的就是那么几个。
1、字符过滤器Character filters
字符过滤器种类不多。elasticearch只提供了三种字符过滤器:
1.1、HTML字符过滤器HTML Strip Char Filter
从文本中去除HTML元素:
POST _analyze
{
"tokenizer": "keyword",
"char_filter": [
"html_strip"
],
"text": "<p>I'm so <b>happy</b>!</p>"
}
执行结果如下:
{
"tokens" : [
{
"token" : """I'm so happy!""",
"start_offset" : 0,
"end_offset" : 27,
"type" : "word",
"position" : 0
}
]
}
1.2、映射字符过滤器Mapping Char Filter
接收键值的映射,每当遇到与键相同的字符串时,它就用该键关联的值替换它们。
PUT pattern_test4
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "keyword",
"char_filter": [
"my_char_filter"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "mapping",
"mappings": [
"hankin => 666",
"chj => 888"
]
}
}
}
}
}
上例中,我们自定义了一个分析器,其内的分词器使用关键字分词器,字符过滤器则是自定制的,将字符中的hankin替换为666,chj替换为888。进行测试:
POST pattern_test4/_analyze
{
"analyzer": "my_analyzer",
"text": " hankin就是chj,hankin只是英文名称!"
}
执行结果:
{
"tokens" : [
{
"token" : " 666就是888,666只是英文名称!",
"start_offset" : 0,
"end_offset" : 26,
"type" : "word",
"position" : 0
}
]
}
1.3、模式替换过滤器Pattern Replace Char Filter
使用正则表达式匹配并替换字符串中的字符。但要小心你写的糟糕的正则表达式,因为这可能导致性能变慢。比如:
POST _analyze
{
"analyzer": "standard",
"text": "My credit card is 123-456-789"
}
这样分词,会导致123-456-789被分为123、456、789,但是我们希望123-456-789 是一个整体,可以使用模式替换过滤器,替换掉“-”。
PUT pattern_test5
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "standard",
"char_filter": [
"my_char_filter"
]
}
},
"char_filter": {
"my_char_filter": {
"type": "pattern_replace",
"pattern": """(\d+)-(?=\d)""",
"replacement": "$1_"
}
}
}
}
}
再次测试:
POST pattern_test5/_analyze
{
"analyzer": "my_analyzer",
"text": "My credit card is 123-456-789"
}
把数字中间的“-”替换为下划线“_”,这样的话可以让“123-456-789”作为一个整体,而不至于被分成123 456 789三部分。
2、分词器Tokenizer
2.1、标准分词器(standard)
标准分词器( standard tokenizer)是一个基于语法的分词器,对于大多数欧洲语言来说是不错的。它还处理了Unicode文本的切分。它也移除了逗号和句号这样的标点符号。
“I have, potatoes.”切分后的分词分别是” I” 、” have” 和” potatoes”。
2.2、关键词分词器(keyword)
关键词分词器( keyword tokenizer )是一种简单的分词器,将整个文本作为单个的分词,提供给分词过滤器。只想应用分词过滤器,而不做任何分词操作时,它可能非常有用。'Hi, there.' 唯一的分词是Hi, there。
2.3、字母分词器(letter)
字母分词器根据非字母的符号,将文本切分成分词。例如,对于句子“Hi,there."分词是Hi和there,因为逗号、空格和句号都不是字母。
2.4、小写分词器(lowercase)
小写分词器( lowercase tokenizer)结合了常规的字母分词器和小写分词过滤器(如你所想,它将整个分词转化为小写)的行为。通过1个单独的分词器来实现的主要原因是,2次进行两项操作会获得更好的性能。
'Hi, there.'分词是hi和 there。
2.5、空白分词器(whitespace)
空白分词器( whitespace tokenizer )通过空白来分隔不同的分词,空白包括空格、制表符、换行等。请注意,这种分词器不会删除任何标点符号,所以文本“Hi, there."的分词是Hi,和there.
2.6、模式分词器(pattern)
模式分词器( patterm tokenizer)允许指定一个任意的模式,将文本切分为分词。被指定的模式应该匹配间隔符号。例如,可以创建一个定制分析器,它在出现文本“. -.”的地方将分词断开。
2.7、UAX URL电子邮件分词器(uax_url_email)
在处理英语单词的时候,标准分词器是非常好的选择。但是,当下存在不少以网站地址和电子邮件地址结束的文本。标准分析器可能在你未注意的地方对其进行了切分。例如,有一个电子邮件地址的样本 john.smith@example.com,用标准分词器分析它,切分后: 'john.smith@example.com'分词是john.smith和example.com。
它同样将URL切分为不同的部分: 'http://example. com?q=foo'分词是 http、example.com、q和foo。UAX URL电子邮件分词器( UAX URL email tokenizer )将电子邮件和URL都作为单独的分词进行保留。
2.8、路径层次分词器(path_hierarchy)
路径层次分词器( path hierarchy tokenizer )允许以特定的方式索引文件系统的路径,这样在搜索时,共享同样路径的文件将被作为结果返回。例如,假设有一个文件名想要索引,看上去是这样的(/var/log/elasticsearch.log。路径层次分词器将其切分为: ' /usr/local/var/1og/elasticsearch. log' 分词是/usr、/usr/local、/usr/local/var、/usr/local/var/ log 和/usr/local/var/log/elasticsearch.1og。
这意味着,一个用户查询时,和上述文件共享同样路径层次(名字也是如此)的文件也会被匹配上。查询“/usr/local/var/log/es.log" 时,它和“/usr/local/var/log/elasticsearch.log" 拥有同样的分词,因此它也会被作为结果返回。
3、分词过滤器(Token filters)
3.1、标准分词过滤器(standard)
不要认为标准分词过滤器( standard token filter )进行了什么复杂的计算,实际上它什么事情也没做。
3.2、小写分词过滤器(lowercase)
小写分词过滤器( lowercase token filter)只是做了这件事:将任何经过的分词转换为小写。这应该非常简单也易于理解。
3.3、长度分词过滤器(length)
长度分词过滤器(length token filter)将长度超出最短和最长限制范围的单词过滤掉。举个例子,如果将min设置为2,并将max设置为8,任何小于2个字符和任何大于8个字符的分词将会被移除。