多字段类型
所谓多字段类型,即:一个字段可以有多个子字段。这种特性带来了以下好处。
- 增加一个keyword子字段,可用于精确匹配
- 可对子字段设置不同的analyzer
- 不通语言的支持
- 可对中文拼音字段进行搜索
- 可对搜索和索引指定不同的Analyzer
精确值和全文本
精确值(Exact Values) vs 全文本(Full Text)
- 精确值,包括数字、日期、具体的字符串(如“192.168.0.1”)
- Elasticsearch中类型为keyword,索引时,不需要做特殊的分词处理
- 全文本,非结构化的文本数据
- Elasticsearch中类型为text,索引时,需要对其进行分词处理
如下结构的数据,我们可以大致判断出哪些是精确值,哪些是全文本。其中的200、info、debug都是精确值。而message的内容为全文本。
- {
- "code": 200,
- "message": "this is a error item, you can change your apollo config !",
- "content": {
- "tags": [
- "info",
- "debug"
- ]
- }
- }
自定义分词器
自定义分词器,可通过组合不同的Character Filter
、Tokenizer
和Token Filter
来实现。
一个 分析器 就是在一个包里面组合了三种函数的一个包装器, 三种函数按照顺序被执行:
Character Filter(
字符过滤器)
字符过滤器 用来 整理
一个尚未被分词的字符串。例如,如果我们的文本是HTML格式的,它会包含像 <p>
或者 <div>
这样的HTML标签,这些标签是我们不想索引的。我们可以使用 html清除
字符过滤器 来移除掉所有的HTML标签,并且像把 Á
转换为相对应的Unicode字符 Á
这样,转换HTML实体。
一个分析器可能有0个或者多个字符过滤器。
Character Filter
,常用的字符过滤器包括:
类型 | 作用 |
---|---|
html_strip | 去除html |
mapping | 字符串替换 |
pattern replace | 正则匹配替换 |
Tokenizer(
分词器)
一个分析器 必须 有一个唯一的分词器。 分词器把字符串分解成单个词条或者词汇单元。 标准
分析器里使用的 标准
分词器 把一个字符串根据单词边界分解成单个词条,并且移除掉大部分的标点符号,然而还有其他不同行为的分词器存在。
例如, 关键词
分词器 完整地输出 接收到的同样的字符串,并不做任何分词。 空格
分词器 只根据空格分割文本 。 正则
分词器 根据匹配正则表达式来分割文本 。
常用的分词器包括:
- whitespace
- standard
- uax_url_email
- pattern
- keyword
- path_hierarchy
Token Filter
(词单元过滤器)
经过分词,作为结果的 词单元流 会按照指定的顺序通过指定的词单元过滤器 。
词单元过滤器可以修改、添加或者移除词单元。 lowercase
和 stop
词过滤器 ,但是在 Elasticsearch 里面还有很多可供选择的词单元过滤器。 词干过滤器 把单词 遏制
为 词干。 ascii_folding
过滤器移除变音符,把一个像 "très"
这样的词转换为 "tres"
。 ngram
和 edge_ngram
词单元过滤器 可以产生 适合用于部分匹配或者自动补全的词单元。
类型 | 作用 |
---|---|
lowercase | 转换为小写 |
stop | 去掉the、a、an等单词 |
synonym | 转换为近义词 |
学习实例
1 使用 Character Filter(
字符过滤器) 中的mapping
- ## 使用 char_filter 的mapping替换 字符
- POST _analyze
- {
- "tokenizer": "standard",
- "char_filter": [
- { "type":"mapping",
- "mappings":[" - => _"]
- }
- ],
- "text": "123-456, I-test! test-990 650-555-1234"
- }
- #char filter 替换表情符号
- POST _analyze
- {
- "tokenizer": "standard",
- "char_filter": [
- {
- "type" : "mapping",
- "mappings" : [ ":) => happy", ":( => sad"]
- }
- ],
- "text": ["I am felling :)", "Feeling :( today"]
- }
2 使用Character Filter(
字符过滤器) 中的
html_strip 去除 html标签
- POST _analyze
- {
- "tokenizer":"keyword",
- "char_filter":["html_strip"],
- "text": "<b>hello world</b>"
- }
3 使用 Token Filter
(词单元过滤器)
- # white space and snowball
- GET _analyze
- {
- "tokenizer": "whitespace",
- "filter": ["stop","snowball"],
- "text": ["The gilrs in China are playing this game!"]
- }
-
- # white space and stop
- POST _analyze
- {
- "tokenizer": "whitespace",
- "filter": ["stop"],
- "text": ["The rain in Spain falls mainly on the plain."]
- }
-
- #remove 加入lowercase后,The被当成 stopword删除
- GET _analyze
- {
- "tokenizer": "whitespace",
- "filter": ["lowercase","stop","snowball"],
- "text": ["The gilrs in China are playing this game!"]
- }
-
- #正则表达式
- GET _analyze
- {
- "tokenizer": "standard",
- "char_filter": [
- {
- "type" : "pattern_replace",
- "pattern" : "http://(.*)",
- "replacement" : "$1"
- }
- ],
- "text" : "http://www.elastic.co"
- }
自定义分析器标准格式是:
- PUT /my_index
- {
- "settings": {
- "analysis": {
- "char_filter": { ... custom character filters ... },//字符过滤器
- "tokenizer": { ... custom tokenizers ... },//分词器
- "filter": { ... custom token filters ... }, //词单元过滤器
- "analyzer": { ... custom analyzers ... }//指定选用的自定义分词器
- }
- }
- }
1 实例 自定义一个分词器:
1)把 & 转换为 and
2)使用自定义 停止
词过滤器移除自定义的停止词列表中包含的词 [ "the", "a" ]
3)使用 html清除
字符过滤器移除HTML部分
- #自定义分词器
- PUT /my_index
- {
- "settings": {
- "analysis": {
- "char_filter": {
- "&_to_and":{
- "type":"mapping",
- "mappings" : [ " &=> and"]
- }
- },
- "filter": {
- "my_stopwords":{
- "type":"stop",
- "stopwords": [ "the", "a" ]
- }
- },
- "analyzer": {
- "myanalyzer":{
- "type":"custom",
- "char_filter":[ "html_strip", "&_to_and" ],
- "tokenizer": "standard",
- "filter": [ "lowercase", "my_stopwords" ]
- }
- }
- }
- }
- }
- 比如自定义好的analyzer名字是my_analyzer,在此索引下的某个新增字段应用此分析器
- PUT /my_index/_mapping
- {
- "properties":{
- "username":{
- "type":"text",
- "analyzer" : "my_analyzer"
- },
- "password" : {
- "type" : "text"
- }
-
- }
- }
- =================插入数据====================
- PUT /my_index/_doc/1
- {
- "username":"The quick & brown fox ",
- "password":"The quick & brown fox "
-
-
- }
- ====username采用自定义分析器my_analyzer,password采用默认的standard分析器==
- ===验证
- GET /index_v1/_analyze
- {
- "field":"username",
- "text":"The quick & brown fox"
- }
-
- GET /index_v1/_analyze
- {
- "field":"password",
- "text":"The quick & brown fox"
- }