analysis-pinyin icon indicating copy to clipboard operation
analysis-pinyin copied to clipboard

又一个关于汉字、拼音、简拼的Completion Suggest的问题

Open IsanHu opened this issue 5 years ago • 8 comments

我的配置:

index

PUT /secom/
  {
      "index" : {
          "analysis" : {
              "analyzer" : {
                  "pinyin_analyzer" : {
                      "tokenizer" : "my_pinyin"
                      }
              },
              "tokenizer" : {
                  "my_pinyin" : {
                      "type" : "pinyin",
                      "keep_first_letter":true,
                      "keep_separate_first_letter" : true,
                      "keep_full_pinyin" : true,
                      "keep_original" : true,
                      "limit_first_letter_length" : 16,
                      "lowercase" : true
                  }
              }
          }
      }
  }

Mapping

POST /secom/words/_mapping 
{
    "words": {
        "properties": {
            "word": {
                "type": "completion",
                "fields": {
                    "pinyin": {
                        "type": "completion",
                        "analyzer": "pinyin_analyzer"
                    }
                }
            }
        }
    }
}

问题:

拼音、简拼的情况下Completion Suggest表现很好

"suggest" : {
    "word-suggest" : [
      {
        "text" : "像kuangfeng",
        "offset" : 0,
        "length" : 10,
        "options" : [
          {
            "text" : "像狂风一样的女子",
            "_index" : "secom",
            "_type" : "words",
            "_id" : "Mq5neGcBBbosGM8MDEVS",
            "_score" : 1.0,
            "_source" : {
              "word" : "像狂风一样的女子"
            }
          }
        ]
      }

但是汉字的情况会补全到其他有类似拼音的词,比如“像”会匹配到“想你”。 怎么设置才能绝对匹配汉字同时能匹配拼音和简拼呢?

"suggest" : {
    "word-suggest" : [
      {
        "text" : "像",
        "offset" : 0,
        "length" : 1,
        "options" : [
          {
            "text" : "像狂风一样的女子",
            "_index" : "secom",
            "_type" : "words",
            "_id" : "zq43eGcBBbosGM8M8kTF",
            "_score" : 1.0,
            "_source" : {
              "word" : "像狂风一样的女子"
            }
          },
          {
            "text" : "想你",
            "_index" : "secom",
            "_type" : "words",
            "_id" : "2a43eGcBBbosGM8M8kTx",
            "_score" : 1.0,
            "_source" : {
              "word" : "想你"
            }
          },
          {
            "text" : "想怎样",
            "_index" : "secom",
            "_type" : "words",
            "_id" : "va43eGcBBbosGM8M8kSP",
            "_score" : 1.0,
            "_source" : {
              "word" : "想怎样"
            }
          }
        ]
      }

IsanHu avatar Dec 04 '18 08:12 IsanHu

大体想了一下,也不尽然是需要汉字匹配的。 因为按照需求的角度来说。 completion suggester 所完成的是一个“快速建议”的 工作。 目的是为了把用户输入的内容进行一个快速过滤,仅仅是过滤一遍有没有类似的内容,一般是通过前缀匹配的方式。 而当使用completion suggester和pinyin插件结合之后,汉字转为pinyin,在pinyin维度,已经没有汉字的识别性,所以也就不存在“像”和“想”不同,只是“xiang”和“xiang”的匹配。

如果你需要在completion suggester的基础确定要加一个类似于前缀匹配汉字的步骤,可以看下 context suggeter

occultskyrong avatar Dec 06 '18 02:12 occultskyrong

不过我还是得提醒,suggester的目的是通过找寻一个专有词库来抛出用户可能想要搜索的内容。。而不是用户一定要搜索的内容。。

这句话的意思是说,假设用户拼音打对了,但是汉字选错了。 比如他想搜索“二级”,结果输入“erji”后输入法选择了“耳机”,这时候你因为完全匹配,推荐的都是“耳机的内容”,与用户期望不符合。

所以,关于这一步,我不建议去强制完全匹配。你只需要给出默认completion suggester的结果即可。

更应该关注的不是suggester的过程,而是结果的反馈,用户选择的什么才是更为关键的。。 你的目的是帮助用户快速的选择符合他心里预期的,而不是你以为他要的。

收集用户在你建议后的行为,诸如选择某个你推荐的值,或者重新输入了内容。 前者你应该把你推荐的那个值的weight提升,后者你应该考虑用户输入的内容是确实没有,还是你推荐的有问题。。


反馈,往往的判断搜索结果的更为靠谱的指标。。

而不是“我以为”。

occultskyrong avatar Dec 06 '18 03:12 occultskyrong

之前写过的一个分析。可以参考下。 https://github.com/occultskyrong/zzone/blob/master/doc/3.0_ElasticSearch/3.0_/ik%2Bpinyin.md

occultskyrong avatar Dec 06 '18 03:12 occultskyrong

之前写过的一个分析。可以参考下。 https://github.com/occultskyrong/zzone/blob/master/doc/3.0_ElasticSearch/3.0_/ik%2Bpinyin.md

好的,感谢

IsanHu avatar Dec 06 '18 03:12 IsanHu

至于这个建议的词库从何而来,不建议直接把内容进行suggester,而是采集用户输入的内容,根据他的反馈。 尤其是第二步的反馈,当某个用户输入pinyin,选择某个建议词进行搜索后,在搜索结果页进行操作,此时需要采集他的信息,比如他点击了第n个,是否产生了跳页行为。

这个时候,先收集他选择的关键词和这个关键词对应的有意义的结果的数量。 前者关键词作为词库的一个元素,后者作为weight的衡量指标。通过分析用户的搜索日志,比如分时,每7、30、90、180天进行一个分数的运算。 比如180天A这个词搜了10遍,90天A这个词搜了5遍,30天搜了3遍,7天搜了1遍,那weight = 10*1+5*2+3*5+7*10来运算,具体的公式可以自己调整。 然后把A这个词收集起来形成一个专有的词库,以后的suggester根据这个词库来。

则更为准确,因为这是用户自己去搜索的内容。

occultskyrong avatar Dec 06 '18 03:12 occultskyrong

比如180天A这个词搜了10遍,90天A这个词搜了5遍,30天搜了3遍,7天搜了1遍,那weight = 10_1+5_2+3_5+7_10来运算,具体的公式可以自己调整。

感谢提供思路!

IsanHu avatar Dec 06 '18 03:12 IsanHu

而当使用completion suggester和pinyin插件结合之后,汉字转为pinyin,在pinyin维度,已经没有汉字的识别性,所以也就不存在“像”和“想”不同,只是“xiang”和“xiang”的匹配。

@occultskyrong 简述一下我这边的情况和需求哈,我们是有一个词库的,是希望引导用户根据我们的词库搜索的。

还想请教的问题:

  • completion suggester能不能实现再加一层过滤呢?过滤掉那些没有搜索词中的汉字的匹配项
  • 我们的词也有weight,completion suggester只会根据我们提供的weight进行排序。能不能实现先根据前缀是否完全匹配排序后再按weight排序?(keep_original我是设置的true,应该是可以的吧。。)

我是ElasticSearch新手,麻烦了不好意思啊

IsanHu avatar Dec 06 '18 07:12 IsanHu

@IsanHu 我遇到跟你一样的问题,我最终的解决方法是,搜索的时候把输入的内容用prefix搜索就可以了。 比如 { "suggest": { "my-suggest" : { "prefix" :“腾讯youxi”, "completion" : { "field" : "name_suggest.pinyin", "size" : suggest_size , "fuzzy":{ "fuzziness":0 } } } } }

morningsky avatar May 27 '19 03:05 morningsky