绊脚石乃是进身之阶。

关于tokenizer与synonym tokenfilter执行顺序的问题

Elasticsearch | 作者 4k_inso | 发布于2021年10月23日 | 阅读数:1048

请教大家一个问题,
软件版本: es 6.8.20 
1. 如下,添加了一个索引
{{url-es}}/goods2/_settings/
{
"settings": {
"analysis": {
"filter": {
"my_synonym_filter": {
"type": "synonym",
"updateable": true
"synonyms_path": "/etc/elasticsearch/analysis/synonym.txt"
}
},
"analyzer": {
"my_synonyms_analyzer": {
"tokenizer": "ik_smart",
"filter": [
"my_synonym_filter"
]
}
}
}
},
"mappings": {
"_doc": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_smart",
"search_analyzer": "my_synonyms_analyzer"
}
}
}
}
}
同义词在文件中设置为 iPhone,苹果手机 => iPhone,苹果手机
之后分析 分词效果
{{url-es}}/goods2/_analyze
{
"analyzer": "my_synonyms_analyzer",
"text": "苹果手机"
}

返回
{
"tokens": [
{
"token": "iphone",
"start_offset": 0,
"end_offset": 4,
"type": "SYNONYM",
"position": 0
},
{
"token": "苹果",
"start_offset": 0,
"end_offset": 2,
"type": "SYNONYM",
"position": 0
},
{
"token": "手机",
"start_offset": 2,
"end_offset": 4,
"type": "SYNONYM",
"position": 1
}
]
}
问题:我的理解是,tokenizer是先于token filter执行的
苹果手机先经过tokenizer分词为 苹果, 手机,然后这两个分词在同义词中都没有对应的结果,那么结果应该只有 苹果,手机;
但是结果还有一个iphone,明显是通过苹果手机直接对应了同义词iphone;那难道是同义词过滤器有特殊情况,
synonym token filter 先于tokenizer执行吗
 
但是我查阅的大部分资料都是说分析器执行顺序是character filter-》tokenzier-》filter

希望有大神解答一下,是不是我漏了什么地方或者理解有问题
 
已邀请:

nofearinmyheat - 新时代农民工

赞同来自:

这个 同义词 的语汇单元过滤器只能接收到在它前面的语汇单元过滤器或者分词器的输出结果(这里看不到原始文本)。摘官网
 
ik_smart分词后确实不会出现“苹果手机”,搞了半天我也没弄明白处理逻辑。。
 
插眼 等个大佬
 
实验过程
PUT /my_synonym
{
"settings": {
"analysis": {
"filter": {
"my_synonym_filter": {
"type": "synonym",
"synonyms": [
"iphone,苹果手机"
]
}
},
"analyzer": {
"my_synonyms": {
"tokenizer": "ik_smart",
"filter": [
"my_synonym_filter"
]
}
}
}
}
}

POST my_synonym/_analyze
{
"explain": true,
"analyzer": "my_synonyms",
"text": ["苹果手机"]
}

运行结果:
{
  "detail" : {
    "custom_analyzer" : true,
    "tokenizer" : {
      "name" : "ik_smart",
      "tokens" : [
        {
          "token" : "苹果",
          "start_offset" : 0,
          "end_offset" : 2,
          "type" : "CN_WORD",
          "position" : 0,
          "bytes" : "[e8 8b b9 e6 9e 9c]",
          "positionLength" : 1,
          "termFrequency" : 1
        },
        {
          "token" : "手机",
          "start_offset" : 2,
          "end_offset" : 4,
          "type" : "CN_WORD",
          "position" : 1,
          "bytes" : "[e6 89 8b e6 9c ba]",
          "positionLength" : 1,
          "termFrequency" : 1
        }
      ]
    },
    "tokenfilters" : [
      {
        "name" : "my_synonym_filter",
        "tokens" : [
          {
            "token" : "苹果",
            "start_offset" : 0,
            "end_offset" : 2,
            "type" : "CN_WORD",
            "position" : 0,
            "bytes" : "[e8 8b b9 e6 9e 9c]",
            "positionLength" : 1,
            "termFrequency" : 1
          },
          {
            "token" : "iphone",
            "start_offset" : 0,
            "end_offset" : 4,
            "type" : "SYNONYM",
            "position" : 0,
            "positionLength" : 2,
            "bytes" : "[69 70 68 6f 6e 65]",
            "positionLength" : 2,
            "termFrequency" : 1
          },
          {
            "token" : "手机",
            "start_offset" : 2,
            "end_offset" : 4,
            "type" : "CN_WORD",
            "position" : 1,
            "bytes" : "[e6 89 8b e6 9c ba]",
            "positionLength" : 1,
            "termFrequency" : 1
          }
        ]
      }
    ]
  }
}

nofearinmyheat - 新时代农民工

赞同来自:

and
不过上文的同义词源定义多少有点小问题,建议参考下官方文档

简单扩展
格式:"jump,hop,leap"
扩展可以应用在索引阶段或查询阶段

简单收缩
格式:"leap,hop => jump"
它必须同时应用于索引和查询阶段,以确保查询词项映射到索引中存在的同一个值。

类型扩展
格式:
"cat   => cat,pet", "kitten => kitten,cat,pet", "dog   => dog,pet" "puppy => puppy,dog,pet"
通过在索引阶段使用类型扩展:查询向下,查询cat会找到关于Kitten和cat相关文档;
或者在查询阶段使用类型扩展, kitten 的查询结果就会被拓展成涉及到 kittens、cats、dogs。【有点疑惑为啥会有dog】

 

要回复问题请先登录注册