ES 終於能夠搜到」悟空哥「了!

zhi'ci回覆 PDF 領取資料 html

這是悟空的第 90 篇原創文章
java

做者 | 悟空聊架構nginx

來源 | 悟空聊架構(ID:PassJava666)git

轉載請聯繫受權(微信ID:PassJava)

Elasticsearch(簡稱 ES)的搜索引擎內置了不少種分詞器,可是對中文分詞不友好,好比搜索悟空哥,是搜不到的,因此咱們須要藉助第三方中文分詞工具包。github

悟空哥專門研究了下 ik 中文分詞工具包該怎麼玩,但願對你們有所幫助。web

本文主要內容以下:docker

主要內容

1 ES 中的分詞的原理

1.1 ES 的分詞器概念

ES 的一個分詞器 ( tokenizer ) 接收一個字符流,將其分割爲獨立的詞元 ( tokens ) ,而後輸出詞元流。vim

ES 提供了不少內置的分詞器,能夠用來構建自定義分詞器 ( custom ananlyzers )瀏覽器

1.2 標準分詞器原理

好比 stadard tokenizer 標準分詞器,遇到空格進行分詞。該分詞器還負責記錄各個詞條 ( term ) 的順序或 position 位置 ( 用於 phrase 短語和 word proximity 詞近鄰查詢 ) 。每一個單詞的字符偏移量 ( 用於高亮顯示搜索的內容 ) 。bash

1.3 英文和標點符號分詞示例

查詢示例以下:

POST _analyze
{
  "analyzer""standard",
  "text""Do you know why I want to study ELK? 2 3 33..."
}

查詢結果:

do, you, know, why, i, want, to, study, elk, 2,3,33

從查詢結果能夠看到:

(1)標點符號沒有分詞。

(2)數字會進行分詞。

英文句子分詞

1.4 中文分詞示例

可是這種分詞器對中文的分詞支持不友好,會將詞語分詞爲單獨的漢字。好比下面的示例會將 悟空聊架構 分詞爲 ,,,,,指望分詞爲 悟空架構

POST _analyze
{
  "analyzer""standard",
  "text""悟空聊架構"
}
中文分詞悟空聊架構

咱們能夠安裝 ik 分詞器來更加友好的支持中文分詞。

2  安裝 ik 分詞器

2.1 ik 分詞器地址

ik 分詞器地址:

https://github.com/medcl/elasticsearch-analysis-ik/releases

先檢查 ES 版本,我安裝的版本是 7.4.2,因此咱們安裝 ik 分詞器的版本也選擇 7.4.2

http://192.168.56.10:9200/
{
  "name" : "8448ec5f3312",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "xC72O3nKSjWavYZ-EPt9Gw",
  "version" : {
    "number" : "7.4.2",
    "build_flavor" : "default",
    "build_type" : "docker",
    "build_hash" : "2f90bbf7b93631e52bafb59b3b049cb44ec25e96",
    "build_date" : "2019-10-28T20:40:44.881551Z",
    "build_snapshot" : false,
    "lucene_version" : "8.2.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
選擇 ik 分詞器

2.2 安裝 ik 分詞器的方式

2.2.1 方式一:容器內安裝 ik 分詞器

  • 進入 es 容器內部 plugins 目錄
docker exec -it <容器 id> /bin/bash
  • 獲取 ik 分詞器壓縮包
wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
  • 解壓縮 ik 壓縮包
unzip 壓縮包
  • 刪除下載的壓縮包
rm -rf *.zip

2.2.2 方式二:映射文件安裝 ik 分詞器

進入到映射文件夾

cd /mydata/elasticsearch/plugins

下載安裝包

wget https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.4.2/elasticsearch-analysis-ik-7.4.2.zip
  • 解壓縮 ik 壓縮包
unzip 壓縮包
  • 刪除下載的壓縮包
rm -rf *.zip

2.2.3 方式三:Xftp 上傳壓縮包到映射目錄

先用 XShell 工具鏈接虛擬機 ( 操做步驟能夠參考以前寫的文章 02. 快速搭建 Linux 環境-運維必備) ,而後用 Xftp 將下載好的安裝包複製到虛擬機。

Xftp 上傳壓縮包

3 解壓 ik 分詞器到容器中

  • 若是沒有安裝 unzip 解壓工具,則安裝 unzip 解壓工具。
apt install unzip
  • 解壓 ik 分詞器到當前目錄的 ik 文件夾下。

命令格式:unzip <ik 分詞器壓縮包>

實例:

unzip ELK-IKv7.4.2.zip -d ./ik
解壓 ik 分詞器
  • 修改文件夾權限爲可讀可寫。
chmod -R 777 ik/
  • 刪除 ik 分詞器壓縮包
rm ELK-IKv7.4.2.zip

4 檢查 ik 分詞器安裝

  • 進入到容器中
docker exec -it <容器 id> /bin/bash
  • 查看 Elasticsearch 的插件
elasticsearch-plugin list

結果以下,說明 ik 分詞器安裝好了。是否是很簡單。

ik
ik 分詞器插件

而後退出 Elasticsearch 容器,並重啓 Elasticsearch 容器

exit
docker restart elasticsearch

5 使用 ik 中文分詞器

ik 分詞器有兩種模式

  • 智能分詞模式 ( ik_smart )

  • 最大組合分詞模式 ( ik_max_word )

咱們先看下 智能分詞 模式的效果。好比對於 一顆小星星 進行中文分詞,獲得的兩個詞語:一顆小星星

咱們在 Dev Tools Console 輸入以下查詢

POST _analyze
{
  "analyzer""ik_smart",
  "text""一顆小星星"
}

獲得以下結果,被分詞爲 一顆和小星星。

一顆小星星分詞結果

再來看下 最大組合分詞模式。輸入以下查詢語句。

POST _analyze
{
  "analyzer""ik_max_word",
  "text""一顆小星星"
}

一顆小星星 被分紅了 6 個詞語:一顆、1、顆、小星星、小星、星星。

一顆小星星分詞結果

咱們再來看下另一箇中文分詞。好比搜索悟空哥聊架構,指望結果:悟空哥、聊、架構三個詞語。

實際結果:悟、空哥、聊、架構四個詞語。ik 分詞器將悟空哥分詞了,認爲 空哥 是一個詞語。因此須要讓 ik 分詞器知道 悟空哥 是一個詞語,不須要拆分。那怎麼辦作呢?

悟空哥聊架構分詞

6 自定義分詞詞庫

6.1 自定義詞庫的方案

  • 方案

    新建一個詞庫文件,而後在 ik 分詞器的配置文件中指定分詞詞庫文件的路徑。能夠指定本地路徑,也能夠指定遠程服務器文件路徑。這裏咱們使用遠程服務器文件的方案,由於這種方案能夠支持熱更新 ( 更新服務器文件,ik 分詞詞庫也會從新加載 ) 。

  • 修改配置文件

ik 分詞器的配置文件在容器中的路徑:

/usr/share/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml。

修改這個文件能夠經過修改映射文件,文件路徑:

/mydata/elasticsearch/plugins/ik/config/IKAnalyzer.cfg.xml

編輯配置文件:

vim /mydata/elasticsearch/plugins/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>

修改配置 remote_ext_dict 的屬性值,指定一個 遠程網站文件的路徑,好比 http://www.xxx.com/ikwords.text。

這裏咱們能夠本身搭建一套 nginx 環境,而後把 ikwords.text 放到 nginx 根目錄。

6.2 搭建 nginx 環境

方案:首先獲取 nginx 鏡像,而後啓動一個 nginx 容器,而後將 nginx 的配置文件拷貝到根目錄,再刪除原 nginx 容器,再用映射文件夾的方式來從新啓動 nginx 容器。

  • 經過 docker 容器安裝 nginx 環境。
docker run -p 80:80 --name nginx -d nginx:1.10
  • 拷貝 nginx 容器的配置文件到 mydata 目錄的 conf 文件夾
cd /mydata
docker container cp nginx:/etc/nginx ./conf
  • mydata 目錄 裏面建立 nginx 目錄
mkdir nginx
  • 移動 conf 文件夾到 nginx 映射文件夾
mv conf nginx/
  • 終止並刪除原 nginx 容器
docker stop nginx
docker rm <容器 id>
  • 啓動新的容器
docker run -p 80:80 --name nginx \
-v /mydata/nginx/html:/usr/share/nginx/html \
-v /mydata/nginx/logs:/var/log/nginx \
-v /mydata/nginx/conf:/etc/nginx \
-d nginx:1.10
  • 訪問 nginx 服務
192.168.56.10

報 403 Forbidden, nginx/1.10.3 則表示 nginx 服務正常啓動。403 異常的緣由是 nginx 服務下沒有文件。

  • nginx 目錄新建一個 html 文件
cd /mydata/nginx/html
vim index.html
hello passjava
  • 再次訪問 nginx 服務

    瀏覽器打印 hello passjava。說明訪問 nginx 服務的頁面沒有問題。

  • 建立 ik 分詞詞庫文件

cd /mydata/nginx/html
mkdir ik
cd ik
vim ik.txt

填寫 悟空哥,並保存文件。

  • 訪問詞庫文件
http://192.168.56.10/ik/ik.txt

瀏覽器會輸出一串亂碼,能夠先忽略亂碼問題。說明詞庫文件能夠訪問到。

  • 修改 ik 分詞器配置
cd /mydata/elasticsearch/plugins/ik/config
vim IKAnalyzer.cfg.xml
修改 ik 分詞器配置
  • 重啓 elasticsearch 容器並設置每次重啓機器後都啓動 elasticsearch 容器。
docker restart elasticsearch
docker update elasticsearch --restart=always
  • 再次查詢分詞結果

能夠看到 悟空哥聊架構 被拆分爲 悟空哥架構 三個詞語,說明自定義詞庫中的 悟空哥 有做用。

終於能夠搜到 悟空哥 了~ ‍‍‍‍‍‍‍‍‍‍‍‍‍‍

- END -

寫了兩本 PDF, 回覆  分佈式  或  PDF  載。
個人 JVM 專欄已上架,回覆  JVM  領取
我的網站: www.passjava.cn

我是悟空,努力變強,變身超級賽亞人!

本文分享自微信公衆號 - 悟空聊架構(PassJava666)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索