赞
踩
分词有什么作用:默认的分词器会将一句话分成一个个单独的字,适用范围广,但是精准度低(索引中和查询语句中有相同的字就会匹配上),所以在配置mapping的时候给需要搜索的中文字段设置分词器,一般需要搜索的中文字段都需要单独设置分词器
"user": { "type": "text", "analyzer": "ik_max_word", "search_analyzer": "ik_max_word" } |
analyzer是字段文本的分词器(建索引时分词),search_analyzer是搜索词的分词器(查询时分词)
ik_max_word: 会将文本做最细粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,中华人民,中华,华人,人民共和国,人民,人,民,共和国,共和,和,国国,国歌”,会穷尽各种可能的组合;
ik_smart: 会做最粗粒度的拆分,比如会将“中华人民共和国国歌”拆分为“中华人民共和国,国歌”。
下载zip包并安装:https://github.com/medcl/elasticsearch-analysis-ik(选择与elasticsearch对应的版本)
按如上步骤或者下载zip包解压到elasticsearch的plugins的ik文件夹下
ik目录下config文件夹IKAnalyzer.cfg.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd"> <properties> <comment>IK Analyzer 扩展配置</comment> <!--用户可以在这里配置自己的扩展字典 --> <entry key="ext_dict">custom/mydict.dic;custom/single_word_low_freq.dic</entry> <!--用户可以在这里配置自己的扩展停止词字典--> <entry key="ext_stopwords">custom/ext_stopword.dic</entry> <!--用户可以在这里配置远程扩展字典 --> <entry key="remote_ext_dict">location</entry> <!--用户可以在这里配置远程扩展停止词字典--> <entry key="remote_ext_stopwords">http://xxx.com/xxx.dic</entry> </properties> |
注意:
如果自定义词典没生效,请确保你的扩展词典的文本格式为 UTF-8 编码,且每个词占一行,例子里的文件路径为相对路径
POST http://localhost:9200/_analyze { "analyzer":"ik_max_word", "text":"死亡人数" } |
已解决(可能存在):
1.需要词典热更新
在apache-tomcat-5.5\webapps\ROOT目录下添加词典,词典需为txt格式并且为UTF-8无bom编码,然后在ik配置文件IKAnalyzer.cfg.xml中配置词典的url http://localhost:端口号/文件名
未解决:
1.设置 "analyzer": "ik_max_word",
"search_analyzer": "ik_max_word"
在词典配置“死亡人数”后,当索引有“死亡人数”,“死亡”,“人数”这几个词的不同语句时,自定义的词“死亡人数”不一定排在前面
index_ansj 是索引分词,尽可能分词处所有结果,词典的词和单个的字都会被分出来
query_ansj 是搜索分词,是索引分词的子集,保证了准确率
dic_ansj 是用户自定义词典优先策略
注:另外几个是别名
下载zip包并安装:https://github.com/NLPchina/elasticsearch-analysis-ansj(选择与elasticsearch对应的版本)
安装方式同ik
如上链接,需注意必须改配置文件,不然词典加载不成功:
#用户自定词典配置 dic: default.dic #也可以写成 file//default.dic , 如果未配置dic,则此词典默认加载 # http方式加载 #dic_d1: http://xxx/xx.dic # jar中文件加载 #dic_d2: jar://org.ansj.dic.DicReader|/dic2.dic # 从数据库中加载 #dic_d3: jdbc:mysql://xxxx:3306/ttt?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull|username|password|select name as name,nature,freq from dic where type=1 # 从自定义类中加载,YourClas extends PathToStream #dic_d3: class://xxx.xxx.YourClas|ohterparam |
dic后的词典文件最好写成file格式的,直接写词典名会包找不到文件的错,自定义词典和默认的词典都写file格式,以.dic结尾,以UTF-8编码
POST http://localhost:9200/_analyze { "analyzer":"index_ansj", "text":"死亡人数" } |
还是分词结果优先级没解决
尝试:
方案一:
改mapping配置为:
"analyzer": "index_ansj",
"search_analyzer": "query_ansj"
可以搜到词典中存在的最长的词,但是query_ansj不能分出更细粒度的词,就如“死亡人数”,query_ansj分词结果为“死亡人数”一个词,“死亡”和“人数”不在分词结果中,与预期结果不符合,同理dic_ansj和query_ansj的分词结果相同。
方案二:
改mapping配置为:
"analyzer": "index_ansj",
"search_analyzer": "index_ansj"
index_ansj分出的词是细粒度的,如“死亡人数”的分词结果是“死亡人数”“死亡”“人数”,满足了对不同词有结果的要求,但同时也将“死亡人数”拆分成四个单独的字存在于分词结果中,这样会大大降低结果的准确性
方案三:ik和ansj结合使用
"analyzer": "ik_max_word",
"search_analyzer": "index_ansj"
和上面结果类似。
也就是说通过设置mapping的分词器方式无法解决这个问题
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。