首页 存档 技术 查看内容

使用Elasticsearch实现博客站内搜索

2018-3-30 13:00 |来自: 互联网 273 0

摘要: 架构师(JiaGouX)我们都是架构师! 一直以来,为了优化本博客站内搜索效果和速度,我使用 bing 的 site: 站内搜索做为数据源,在服务端获取、解析、处理并缓存搜索结果,直接输出 HTML。这个方案唯一的问题是时效 ...

架构师(JiaGouX)
我们都是架构师!


一直以来,为了优化本博客站内搜索效果和速度,我使用 bing 的 site: 站内搜索做为数据源,在服务端获取、解析、处理并缓存搜索结果,直接输出 HTML。这个方案唯一的问题是时效性难以保证,尽管我可以在发布和修改文章时主动告诉 bing,但它什么时候更新索引则完全不受我控制。

本着不折腾就浑身不自在的原则,我最终还是使用 Elasticsearch 搭建了自己的搜索服务。Elasticsearch 是一个基于 Lucene 构建的开源、分布式、RESTful 搜索引擎,很多大公司都在用,程序员的好伙伴 Github 的搜索也用的是它。本文记录我使用 Elasticsearch 搭建站内搜索的过程,目前支持中文分词、同义词、标题匹配优先等常见策略,请「点击这里」体验。

安装 Elasticsearch

部署 Elasticsearch 最简单的方法是使用 Elasticsearch Dockerfile。为了更彻底地折腾,我没有使用 Docker,好在手动安装过程也不复杂。

我的虚拟机和线上环境都是 Ubuntu 14.04.3 LTS,Elasticsearch 用的是目前最新的 2.1.1。一切开始之前,先要检查机器上是否装有 java 环境,如果没有可以通过以下命令安装:

sudo apt-get install openjdk-7-jre-headless

下载 Elasticsearch 2.1.1 压缩包并解压:

https://download.elasticsearch.org/elasticsearch/release/org/elasticsearch/distribution/zip/elasticsearch/2.1.1/elasticsearch-2.1.1.zip

unzip elasticsearch-2.1.1.zip

我将解压得到的 elasticsearch-2.1.1 目录重命名为 ~/es_root(名称及位置没有**,可以将它挪到你认为合适的任何位置)。Elasticsearch 无需安装,直接可以运行:

cd ~/es_root/bin/

chmod a x elasticsearch

./elasticsearch

如果屏幕上没有打印错误信息,说明 Elasticsearch 服务已经成功启动。新建一个终端,用 curl 验证下:

curl -XGET http://127.0.0.1:9200/?pretty

{

"name" : "Goblyn",

"cluster_name" : "elasticsearch",

"version" : {

"number" : "2.1.1",

"build_hash" : "40e2c53a6b6c2972b3d13846e450e66f4375bd71",

"build_timestamp" : "2015-12-15T13:05:55Z",

"build_snapshot" : false,

"lucene_version" : "5.3.1"

},

"tagline" : "You Know, for Search"

}

如果看到以上信息,说明一切正常,否则请根据屏幕上的错误信息查找原因。尽管 Elasticsearch 本身是用 java 写的,但它对外可以通过 RESTful 接**互,十分方便。

默认情况下 Elasticsearch 的 RESTful 服务只有本机才能访问,也就是说无法从主机访问虚拟机中的服务。为了方便调试,可以修改 ~/es_root/config/elasticsearch.yml 文件,加入以下两行:

network.bind_host: "0.0.0.0"

network.publish_host: _non_loopback:ipv4_

但线上环境切忌不要这样配置,否则任何人都可以通过这个接口修改你的数据。

安装 IK Analysis

Elasticsearch 自带的分词器会粗暴地把每个汉字直接分开,没有根据词库来分词。为了处理中文搜索,还需要安装中文分词插件。我使用的是 elasticsearch-analysis-ik,支持自定义词库。

首先,下载与 Elasticsearch 2.1.1 匹配的 elasticsearch-analysis-ik 插件。根据文档,当前需要使用 master 版:

wget -c https://github.com/medcl/elasticsearch-analysis-ik/archive/master.zip

unzip master.zip

解压后,进入插件源码目录编译:

sudo apt-get install maven

cd elasticsearch-analysis-ik-master/

mvn package

如果一切顺利,在 target/releases/ 目录下可以找到编好的文件。将其解压并拷到 ~/es_root 对应目录:

mkdir -p ~/es_root/plugins/ik/

unzip target/releases/elasticsearch-analysis-ik-1.6.2.zip -d ~/es_root/plugins/ik/

再将 elasticsearch-analysis-ik 的配置也拷贝到 ~/es_root 对应目录:

mkdir -p ~/es_root/config/ik

cp -r config/ik/* ~/es_root/config/ik/

elasticsearch-analysis-ik 的配置文件中很多都是词表,直接用文本编辑器打开就可以修改,改完记得保存为 utf-8 格式。

现在再启动 Elasticsearch 服务,如果看到类似下面这样的信息,说明 IK Analysis 插件已经装好了:

[plugins] [Libra] loaded [elasticsearch-analysis-ik]

配置同义词

Elasticsearch 自带一个名为 synonym 的同义词 filter。为了能让 IK 和 synonym 同时工作,我们需要定义新的 analyzer,用 IK 做 tokenizer,synonym 做 filter。听上去很复杂,实际上要做的只是加一段配置。

打开 ~/es_root/config/elasticsearch.yml 文件,加入以下配置:

index:

analysis:

analyzer:

ik_syno:

type: custom

tokenizer: ik_max_word

filter: [my_synonym_filter]

ik_syno_smart:

type: custom

tokenizer: ik_smart

filter: [my_synonym_filter]

filter:

my_synonym_filter:

type: synonym

synonyms_path: analysis/synonym.txt

以上配置定义了 ik_syno 和 ik_syno_smart 这两个新的 analyzer,分别对应 IK 的 ik_max_word 和 ik_smart 两种分词策略。根据 IK 的文档,二者区别如下:

  • ik_max_word:会将文本做最细粒度的拆分,例如「中华人民共和国国歌」会被拆分为「中华人民共和国、中华人民、中华、华人、人民共和国、人民、人、民、共和国、共和、和、国国、国歌」,会穷尽各种可能的组合;

  • ik_smart:会将文本做最粗粒度的拆分,例如「中华人民共和国国歌」会被拆分为「中华人民共和国、国歌」;

ik_syno 和 ik_syno_smart 都会使用 synonym filter 实现同义词转换。为了方便后续测试,建议创建~/es_root/config/analysis/synonym.txt 文件,输入一些同义词并存为 utf-8 格式。例如:

ua,user-agent,userAgent

js,javascript

internet explore=

声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

相关分类

返回顶部