ElasticSearch的一点点使用经验

为啥要使用

用户要搜索嘛,传统的mysql like语句不满足要求,需要更强大的搜索工具。

安装方法

先安装Java

sudo yum install java-1.8.0-openjdk.x86_64

官方源安装

使用添加es官方安装源的方式,这里就不重新复制一份了参考这里安装吧:官方源安装ES步骤

导入数据

创建索引首先需要创建索引

curl -XPOST http://127.0.0.1:9200/some_index -d'
{
"mappings": {
"my_type": {
"properties": {
"date": {
"type": "date",
"format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
},
"settings": {
"analysis": {
"char_filter": {
"escape_sign": {
"type": "mapping",
"mappings": [
"@=>qsdvhi" //用户搜索的时候,把@转换为某个字符串
]
}
},
"analyzer": {
"my_analyzer": {
"type": "custom",
"char_filter": ["html_strip", "escape_sign", "tsconvert"], //繁体转简单
"tokenizer": "ik_max_word", //使用IK中文分词
"filter": [ "lowercase"]
}}
}}
}'

创建对应的表

curl -XPOST http://127.0.0.1:9200/some_index/photo/_mapping -d '
{
"photo": {
"properties": {
"id": {
"type": "long"
},
"out_id": {
"type": "long"
},
"path": {
"type": "string"
},
"status": {
"type": "long"
},
"desc": {
"type": "string",
"analyzer": "my_analyzer", //指定上面定义的分析器
"search_analyzer": "my_analyzer",
"term_vector": "with_positions_offsets"
},
"created_at": {
"type": "date",
"format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
},
"updated_at": {
"type": "date",
"format": "yyy-MM-dd HH:mm:ss||yyyy-MM-dd||epoch_millis"
}
}
}
}'

删除无用的索引

curl -XDELETE http://127.0.0.1:9200/some_index

接着使用PHP的ES包来导入数据:laravel-elasticsearch,如何使用可以参考包内的说明。

中文分词

分词采用 IK Analysis for Elasticsearch,首先需要安装Java的打包工具mvn,然后checkout上面github上面的代码,执行打包命令

mvn package

打包完成后会生成target目录

├── config
│   └── ik
├── LICENSE.txt
├── pom.xml
├── README.md
├── src
│   └── main
└── target
├── archive-tmp
├── classes
├── elasticsearch-analysis-ik-1.8.0.jar
├── elasticsearch-analysis-ik-1.8.0-sources.jar
├── generated-sources
├── maven-archiver
├── releases
└── surefire
11 directories, 5 files

接着拷贝解压出target/releases/elasticsearch-analysis-ik-1.8.0.zip到ES根目录下的plugins目录(如果没有新建一个即可)下即可

本本地的ArchLinux以及线上的CentOS均是位于如下目录

/usr/share/elasticsearch
目录结构如下所示:
plugins/
└── ik
├── commons-codec-1.9.jar
├── commons-logging-1.2.jar
├── config
│   └── ik
│   ├── custom
│   │   ├── ext_stopword.dic
│   │   ├── mydict.dic
│   │   ├── single_word.dic
│   │   ├── single_word_full.dic
│   │   ├── single_word_low_freq.dic
│   │   └── sougou.dic
│   ├── IKAnalyzer.cfg.xml
│   ├── main.dic
│   ├── preposition.dic
│   ├── quantifier.dic
│   ├── stopword.dic
│   ├── suffix.dic
│   └── surname.dic
├── elasticsearch-analysis-ik-1.8.0.jar
├── elasticsearch-analysis-ik-1.8.0.zip
├── httpclient-4.4.1.jar
├── httpcore-4.4.1.jar
└── plugin-descriptor.properties
4 directories, 20 files

需要注意的是plugins下的文件用户和组需要设置为:elasticsearch,否则会导致ES启动不了

chown -R elasticsearch:elasticsearch plugins/

重启ES后就可以在对应的索引里头把analyzer修改成ik对应的几个分词器了!

还有另外几个中文分词插件,有空可以尝试一下,看ansj的描述好像挺牛逼的样子,但是我安上后会导致ES无限重启,不知道啥原因。

elasticsearch-analysis-ansj
elasticsearch-analysis-mmseg

简繁转换

使用 STConvert Analysis for Elasticsearch 来进行繁体到简单的转换,代码clone下来后,使用mvn命令打包一下

mvn package

打包成功后,可以在target/release目录内找到对应的包

[INFO] Reading assembly descriptor: /home/vagrant/dev/elasticsearch-analysis-stconvert/src/main/assemblies/plugin.xml
[INFO] Building zip: /home/vagrant/dev/elasticsearch-analysis-stconvert/target/releases/elasticsearch-analysis-stconvert-1.8.3.zip
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 12:06 min
[INFO] Finished at: 2016-06-22T14:26:37+08:00
[INFO] Final Memory: 32M/212M
[INFO] ------------------------------------------------------------------------

编辑插件包的时候千万注意版本问题,否则ES会报插件版本不符合的!

同义词搜索

TODO 这块暂时还没空折腾,等后面分析用户的搜索词后再处理。

特殊符号的搜索

有接到用户的反馈信息,说不支持@符号的搜索,研究了1天时间,发现有以下两种方式可以做到

索引数据时替换@符号

为啥会搜索不到@符号呢?因为ES在索引的时候默认认为他们都是无用字符,然后把这些标点符号全部干掉。

解决思路很简单就是在索引的时候把@符号替换成某个对应字符串(一定不要是常用字符串)比如:uhbbgt,然后在索引进ES库中。在检索的时候使用mapping把@符号再替换为uhbbgt即可。

这块思路来源于官方文档里面里头的这个:Symbol Synonyms, 而mapping的语法可以参考:Mapping Char Filter

修改分词插件

这块我也只敢想想,不会Java改不动哈!

遇到的相关小问题

query phase execution exception result window is too large

这个是一个比较常见的问题了,最简单的方式就是增大窗口

curl -XPUT "http://localhost:9200/some_index/_settings" -d '{ "index" : { "max_result_window" : 100000 } }'