Введение в Elasticsearch — основные понятия и китайский токенизатор IK

Elasticsearch

Резюме учебных материалов

Overview

открытый источникElasticsearch(именуемый в дальнейшемElastic) в настоящее время является первым выбором для полнотекстовых поисковых систем. Он может быстро хранить, искать и анализировать огромные объемы данных и используется Википедией, Stack Overflow и Github.

В основе Elastic лежат библиотеки с открытым исходным кодом.Lucene. Однако вы не можете напрямую использоватьLucene, вы должны написать свой собственный код для вызова его интерфейса.ElasticдаLuceneпакет, который обеспечиваетREST APIИнтерфейс работы из коробки.

FAQ

Версия токенайзера и ES не совпадают

воплощать в жизньelasticsearchПри запуске ES возникает следующая ошибка, указывающая на то, что версия токенизатора и версия ES не совпадают.

Plugin [analysis-ik] was built for Elasticsearch version 7.6.1 but version 7.9.1 is running

Решение — переустановить токенизатор, соответствующий версии. Ссылаться наelasticsearch-analysis-ik | github.

./bin/elasticsearch-plugin install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.9.1/elasticsearch-analysis-ik-7.9.1.zip

Конфигурация установки ЕС

  1. Установите ElasticSearch с Homebrew
brew tap elastic/tap

brew install elastic/tap/elasticsearch-full
  1. Каталог установки ES по умолчанию
Type Description Default Location Setting
home Elasticsearch home directory or $ES_HOME /usr/local/var/homebrew/linked/elasticsearch-full
conf Configuration files including elasticsearch.yml /usr/local/etc/elasticsearch ES_PATH_CONF
data /usr/local/var/lib/elasticsearch path.data
logs /usr/local/var/log/elasticsearch path.logs
plugins /usr/local/var/homebrew/linked/elasticsearch/plugins
  1. На данный момент тестовая среда ES настроена. Прежде чем приступить к формальной разработке, необходимо выполнить следующие дополнительные шаги.
  1. Ниже приведен простой запуск, чтобы убедиться, что конфигурация выполнена успешно.
  • выполнить в терминалеelasticsearch, запустите ЭС. Если вы столкнетесьmax virtual memory areas vm.maxmapcount [65530] is too lowОшибка, вы можете выполнить следующую команду
sudo sysctl -w vm.max_map_count=262144
  • Если все пойдет хорошо, Elastic9200порт работает. В это время откройте другое окно командной строки, запросите порт, и вы получите информацию описания
ZBMAC-b286c5fb6:~ liubaoshuai1$ curl localhost:9200
{
  "name" : "ZBMAC-b286c5fb6",
  "cluster_name" : "elasticsearch_liubaoshuai1",
  "cluster_uuid" : "v6A5SuX2RI2Clgs30qhq7g",
  "version" : {
    "number" : "7.6.2",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "ef48eb35cf30adf4db14086e8aabd07ef6fb113f",
    "build_date" : "2020-03-26T06:34:37.794943Z",
    "build_snapshot" : false,
    "lucene_version" : "8.4.0",
    "minimum_wire_compatibility_version" : "6.8.0",
    "minimum_index_compatibility_version" : "6.0.0-beta1"
  },
  "tagline" : "You Know, for Search"
}
  • В приведенном выше коде запрос9200Port, Elastic возвращает объект JSON, содержащий такую ​​информацию, как текущий узел, кластер, версия и т. д.
  • Нажмите Ctrl + C, и Elastic перестанет работать.
  • По умолчанию Elastic разрешает только локальный доступ, если вам нужен удаленный доступ, вы можете изменить каталог установки Elastic.config/elasticsearch.ymlфайл, удалитьnetwork.hostкомментарий, измените его значение на0.0.0.0, затем перезапустите Elastic. установлен в0.0.0.0Указывает, что любой может получить доступ. Не устанавливайте онлайн-сервис таким образом, установите для него определенный IP-адрес.
network.host: 0.0.0.0
  1. catКоманды могут помочь разработчикам быстро запрашивать информацию, связанную с Elasticsearch.
  • использовать_catМожет просматривать поддерживаемые команды
ZBMAC-b286c5fb6:~ liubaoshuai1$ curl localhost:9200/_cat
=^.^=
/_cat/allocation
/_cat/shards
/_cat/shards/{index}
/_cat/master
/_cat/nodes
/_cat/tasks
/_cat/indices
/_cat/indices/{index}
/_cat/segments
/_cat/segments/{index}
/_cat/count
/_cat/count/{index}
/_cat/recovery
/_cat/recovery/{index}
/_cat/health
/_cat/pending_tasks
/_cat/aliases
/_cat/aliases/{alias}
/_cat/thread_pool
/_cat/thread_pool/{thread_pools}
/_cat/plugins
/_cat/fielddata
/_cat/fielddata/{fields}
/_cat/nodeattrs
/_cat/repositories
/_cat/snapshots/{repository}
/_cat/templates
  • Каждая команда поддерживает использование?vпараметры для отображения подробной информации
ZBMAC-b286c5fb6:~ liubaoshuai1$ curl localhost:9200/_cat/master?v
id                     host      ip        node
KqsnRZTeRbeKimt8XfGAoQ 127.0.0.1 127.0.0.1 ZBMAC-b286c5fb6
  • Каждая команда поддерживает использованиеhelpпараметр для вывода столбцов, которые могут отображаться
ZBMAC-b286c5fb6:~ liubaoshuai1$ curl localhost:9200/_cat/master?help
id   |   | node id    
host | h | host name  
ip   |   | ip address 
node | n | node name 
  • пройти черезhПараметры, можно указать поля вывода
ZBMAC-b286c5fb6:~ liubaoshuai1$ curl localhost:9200/_cat/master?v
id                     host      ip        node
KqsnRZTeRbeKimt8XfGAoQ 127.0.0.1 127.0.0.1 ZBMAC-b286c5fb6
ZBMAC-b286c5fb6:~ liubaoshuai1$ curl localhost:9200/_cat/master?h=host,ip,node
127.0.0.1 127.0.0.1 ZBMAC-b286c5fb6
  • Форматирование числовых типов. Многие команды поддерживают возврат удобочитаемых больших и малых чисел, например, использованиеmbилиkbПредставлять
ZBMAC-b286c5fb6:~ liubaoshuai1$ curl localhost:9200/_cat/indices?v
health status index uuid pri rep docs.count docs.deleted store.size pri.store.size

Основные понятия ЭС

Концептуальная аналогия между концепциями ES и реляционных баз данных показана в следующей таблице.

Relational Database Elasticsearch
Database Index
Table Type
Row Document
Column Field
Scheme Mapping
Index Everything is indexed
SQL Query DSL
SELECT * FROM ... GET http://...
UPDATE table_name SET ... PUT http://...

Совет: Лучше всего создавать только один тип под одним индексом в ES, а не создавать несколько типов.

Узел и кластер

Elastic — это, по сути, распределенная база данных, которая позволяет нескольким серверам работать вместе, каждый из которых может запускать несколько экземпляров Elastic.

Один экземпляр Elastic называется узлом (node). Группа узлов образует кластер (cluster).

Index

Elastic индексирует все поля, обрабатывает их и записывает в инвертированный индекс (Inverted Index). При поиске данных ищите индекс напрямую.

так,Модуль верхнего уровня управления эластичными данными называетсяIndex(показатель). Это синоним единой базы данных. каждыйIndex(т.е. базы данных) имена должны быть в нижнем регистре.

Следующая команда может просмотреть все индексы текущего узла.

$ curl -X GET 'http://localhost:9200/_cat/indices?v'

Document

Одна запись в указателе называетсяDocument(документация). многиеDocumentсоставляет Индекс.

Документ представлен в формате JSON, пример ниже.

{
  "user": "张三",
  "title": "工程师",
  "desc": "数据库管理"
}

Документы в одном индексе не обязательно должны иметь одинаковую структуру (схему), но лучше, чтобы они были одинаковыми, что способствует повышению эффективности поиска.

Type

Документы могут быть сгруппированы, например.weatherВ этом Индексе вы можете группировать по городам (Пекин и Шанхай) или по климату (солнечный и дождливый). Эта группировка называетсяType,Это виртуальная логическая группа, используемая для фильтрации документов..

Разные типы должны иметь схожие структуры (schema), например, поле id не может быть строкой в ​​одной группе и числовым значением в другой. Это связано с таблицей реляционной базы данныхразница. данные совершенно другого характера (такие какproductsиlogs) следует хранить как два индекса, а не два типа в одном индексе (хотя это можно сделать).

Следующая команда перечисляет типы, содержащиеся в каждом индексе.

$ curl 'localhost:9200/_mapping?pretty=true'

Согласно плану, версия Elastic 6.x позволяет каждому индексу содержать только один тип, а версия 7.x полностью удалит тип.

Плагин визуализации elasticsearch-head

A web front end for an Elasticsearch cluster

elasticsearch-headШаги установки следующие

  1. Загрузите исходный код и установите зависимости
git clone git://github.com/mobz/elasticsearch-head.git

cd elasticsearch-head

npm install

npm run start
  1. 【Рекомендуется использовать этот метод】Доступhttp://localhost:9100/

Следует отметить, что его также можно установить через плагин Chrome, см.elasticsearch-head | github.

Платформа визуализации Kibana

Kibana — это платформа аналитики и визуализации с открытым исходным кодом для Elasticsearch для поиска, просмотра и взаимодействия с данными, хранящимися в индексах Elasticsearch.

  1. Установите Kibana с Homebrew
brew tap elastic/tap

brew install elastic/tap/kibana-full
lbsMacBook-Pro:~ lbs$ brew install elastic/tap/kibana-full
==> Installing kibana-full from elastic/tap
==> Downloading https://artifacts.elastic.co/downloads/kibana/kibana-7.6.2-darwin-x86_64.tar.gz?tap=elastic/homebrew-tap
######################################################################## 100.0%
==> Caveats
Config: /usr/local/etc/kibana/
If you wish to preserve your plugins upon upgrade, make a copy of
/usr/local/opt/kibana-full/plugins before upgrading, and copy it into the
new keg location after upgrading.

To have launchd start elastic/tap/kibana-full now and restart at login:
  brew services start elastic/tap/kibana-full
Or, if you don't want/need a background service you can just run:
  kibana
==> Summary
🍺  /usr/local/Cellar/kibana-full/7.6.2: 99,457 files, 689.8MB, built in 7 minutes 17 seconds
  1. Путь установки Kibana по умолчанию показан в следующей таблице.
Type Description Default Location Setting
home Kibana home directory or $KIBANA_HOME /usr/local/var/homebrew/linked/kibana-full
bin Binary scripts including kibana to start a node and kibana-plugin to install plugins /usr/local/var/homebrew/linked/kibana-full/bin
conf Configuration files including kibana.yml /usr/local/etc/kibana
data The location of the data files of each index / shard allocated on the node. Can hold multiple locations. /usr/local/var/lib/kibana path.data
logs Log files location. /usr/local/var/log/kibana path.logs
plugins Plugin files location. Each plugin will be contained in a subdirectory. /usr/local/var/homebrew/linked/kibana-full/plugins
  1. Начать поиск в эластиссе
  2. начать кибана
lbsMacBook-Pro:~ lbs$ elasticsearch
lbsMacBook-Pro:~ lbs$ kibana

//后台启动
nohup nice kibana &  
  1. доступhttp://localhost:5601/Может видеть панель Kibana
  2. доступhttp://localhost:5601/statusМожет просматривать статус Kibana

Индекс Создать/Удалить

новыйIndex, вы можете отправить запрос PUT непосредственно на сервер Elastic. В следующем примере создается новыйweatherИндекс.

$ curl -X PUT 'localhost:9200/weather'

Сервер возвращает объект JSON сacknowledgedполе указывает на то, что операция прошла успешно.

{
  "acknowledged":true,
  "shards_acknowledged":true
}

Затем мы выдаем запрос DELETE для удаления индекса.

$ curl -X DELETE 'localhost:9200/weather'

{
   "acknowledged":true
}

манипуляция данными

FAQ

Если во время работы с данными вы столкнулись со следующей ошибкой, вы можете обратиться к приведенной выше ссылке, чтобы решить ее.

elasticsearch6.x {"error":"Content-Type header [application/x-www-form-urlencoded] is not supported"

The Elasticsearch engineering team is busy working on features for Elasticsearch 6.0. One of the changes that is coming in Elasticsearch 6.0 is strict content-type checking.

Starting from Elasticsearch 6.0, all REST requests that include a body must also provide the correct content-type for that body. --- elasticsearch6.x {"ошибка": "Заголовок Content-Type [application/x-www-form-urlencoded] не поддерживается" — официальное исправление

После ES 6.0 строгийcontent-typeПроверьте, нужно добавить-H'Content-Type: application/json'Аргументы находятся в командной строке. Например

curl -X PUT 'localhost:9200/accounts/person/1' -d '
{
  //...
}' 

необходимо обновить до

curl -H'Content-Type: application/json' -X PUT 'localhost:9200/accounts/person/1' -d '
{
  //...
}' 

Добавить запись

к указанному/Index/TypeОтправьте запрос PUT, чтобы добавить новую запись в индекс. Например, чтобы/accounts/personОтправьте запрос на добавление записи человека.

ZBMAC-b286c5fb6:~ liubaoshuai1$ curl -H "Content-Type: application/json" -X PUT 'localhost:9200/accounts/person/1' -d '
> {
>   "user": "张三",
>   "title": "工程师",
>   "desc": "数据库管理"
> }'

Объект JSON, возвращаемый сервером, предоставит индекс, тип, идентификатор, версию и другую информацию.

{           
    "_index":"accounts",
    "_type":"person",
    "_id":"1",
    "_version":1,
    "result":"created",
    "_shards":{"total":2,"successful":1,"failed":0},
    "_seq_no":0,
    "_primary_term":1
 }

Если вы посмотрите внимательно, вы обнаружите, что путь запроса/accounts/person/1,Последний1этой записиId. Это не обязательно должно быть число, любая строка (например,abc) Все будет хорошо.

При добавлении записи также можно не указыватьId, затем измените его наPOSTпросить.

$ curl -H "Content-Type: application/json" -X POST 'localhost:9200/accounts/person' -d '
{
  "user": "李四",
  "title": "工程师",
  "desc": "系统管理"
}'

В это время в объекте JSON, возвращаемом сервером,_idПоле — это просто случайная строка.

{
  "_index":"accounts",
  "_type":"person",
  "_id":"A9QxNXEBLRNcEQlvnE1_",
  "_version":1,
  "result":"created",
  "_shards":{"total":2,"successful":1,"failed":0},
  "_seq_no":2,
  "_primary_term":2
}

Просмотр записей

В направлении/Index/Type/IdЭту запись можно просмотреть, отправив запрос GET.

URL-параметрыpretty=trueУказывает, что он возвращается в удобочитаемом формате.

В возвращенных данныхfoundполе указывает, что запрос выполнен успешно,_sourceполе возвращает исходную запись.

$ curl 'localhost:9200/accounts/person/1?pretty=true'

{
  "_index" : "accounts",
  "_type" : "person",
  "_id" : "1",
  "_version" : 2,
  "_seq_no" : 1,
  "_primary_term" : 2,
  "found" : true,
  "_source" : {
    "user" : "张三",
    "title" : "工程师",
    "desc" : "数据库管理"
  }
}

Удалить запись

Чтобы удалить запись, нужно выполнить запрос DELETE.

$ curl -X DELETE 'localhost:9200/accounts/person/1'

обновить запись

Чтобы обновить запись, нужно использовать запрос PUT для повторной отправки данных.

$ curl -H "Content-Type: application/json" -X PUT 'localhost:9200/accounts/person/1' -d '
{
    "user" : "张三",
    "title" : "工程师",
    "desc" : "数据库管理,软件开发"
}' 

Можно обнаружить, что в возвращаемом объекте JSON записанныйIdбез изменений, но версия (version) изменился, тип операции (result)отcreatedстатьupdated,createdполе становитсяfalse, потому что на этот раз это не новый рекорд.

{
  "_index":"accounts",
  "_type":"person",
  "_id":"1",
  "_version":3,
  "result":"updated",
  "_shards":{"total":2,"successful":1,"failed":0},
  "_seq_no":3,
  "_primary_term":2
}

Кроме того, чтобы отформатировать возвращенный объект JSON, вы можете выполнить следующие шаги.

  1. npm установить глобальноjson:npm install -g json
  2. После указанных выше параметров команды добавьте| json
  3. Если вы не хотите показыватьcurlстатистику можно добавить-sпараметры (см.Curl не показывает статистику % Total % Received % | Short Book)
$ curl -H "Content-Type: application/json" -X PUT 'localhost:9200/accounts/person/1' -d '
{
    "user" : "张三",
    "title" : "工程师",
    "desc" : "数据库管理,软件开发"
}'  |json

запрос данных

вернуть все записи

Использовать метод GET, прямой запрос/Index/Type/_search, будут возвращены все записи.

$ curl 'localhost:9200/accounts/person/_search'

{
    "took": 629,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 2,
            "relation": "eq"
        },
        "max_score": 1,
        "hits": [
            {
                "_index": "accounts",
                "_type": "person",
                "_id": "A9QxNXEBLRNcEQlvnE1_",
                "_score": 1,
                "_source": {
                    "user": "李四",
                    "title": "工程师",
                    "desc": "系统管理"
                }
            },
            {
                "_index": "accounts",
                "_type": "person",
                "_id": "1",
                "_score": 1,
                "_source": {
                    "user": "张三",
                    "title": "工程师",
                    "desc": "数据库管理,软件开发"
                }
            }
        ]
    }
}

В приведенном выше коде возвращается результатtookПоле указывает длительность операции (в миллисекундах),timed_outПоле указывает, истекло ли время ожидания,hitsПоле представляет собой запись попадания, а значения подполей следующие:

  • total: возвращает количество записей
  • max_score: высшая степень соответствия
  • hits: массив возвращенных записей

исследовать все

Запрос Elastic очень особенный, используйте свой собственныйсинтаксис запроса, требуется запрос GET с телом данных.

$ curl -H "Content-Type: application/json" 'localhost:9200/accounts/person/_search'  -d '
{
  "query" : { "match" : { "desc" : "软件" }}
}'

Используйте приведенный выше кодСопоставить запрос, заданное условие совпаденияdescПоле содержит слово «программное обеспечение». Возвращаемый результат выглядит следующим образом.

{
    "took": 33,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "skipped": 0,
        "failed": 0
    },
    "hits": {
        "total": {
            "value": 1,
            "relation": "eq"
        },
        "max_score": 1.1978253,
        "hits": [
            {
                "_index": "accounts",
                "_type": "person",
                "_id": "1",
                "_score": 1.1978253,
                "_source": {
                    "user": "张三",
                    "title": "工程师",
                    "desc": "数据库管理,软件开发"
                }
            }
        ]
    }
}

Elastic по умолчанию возвращает 10 результатов за раз, вы можете пройтиsizeполе для изменения этого параметра. также черезfromполе определяет смещение.

$ curl -H "Content-Type: application/json" 'localhost:9200/accounts/person/_search'  -d '
{
  "query" : { "match" : { "desc" : "管理" }},
  "size": 20   //定义size
  “from": 1,   // 从位置1开始(默认是从位置0开始)
}'

логическая операция

Если есть несколько ключевых слов для поиска, Elastic считает их или (or) отношение.

$ curl -H "Content-Type: application/json"  'localhost:9200/accounts/person/_search'  -d '
{
  "query" : { "match" : { "desc" : "软件 系统" }}
}'

Приведенный выше код ищет软件 or 系统.

Если вы хотите выполнить несколько ключевых словandпоиск, надо использоватьлогический запрос.

$ curl -H "Content-Type: application/json" 'localhost:9200/accounts/person/_search'  -d '
{
  "query": {
    "bool": {
      "must": [
        { "match": { "desc": "软件" } },
        { "match": { "desc": "系统" } }
      ]
    }
  }
}'

Настройки сегментации китайских слов

IK Online Tokenizer

Причастия основные понятия

Когда документ сохраняется, ES использует токенизатор для извлечения нескольких токенов из документа (token) для поддержки хранения индексов и поиска. В ES много встроенных токенизаторов, но встроенные токенизаторы плохо справляются с китайским языком. Давайте возьмем пример, чтобы увидеть обработку встроенного токенизатора. Инициируйте следующий запрос REST в веб-клиенте, чтобы сегментировать английское предложение.

curl -H "Content-Type: application/json" -PUT 'localhost:9200/_analyze' -d '
{  
    "text": "hello world"  
}' | json

// |json 表示对返回结果进行json化展示

Результат возврата следующий

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   213  100   179  100    34  44750   8500 --:--:-- --:--:-- --:--:-- 53250
{
  "tokens": [
    {
      "token": "hello",
      "start_offset": 0,
      "end_offset": 5,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "world",
      "start_offset": 6,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 1
    }
  ]
}

Приведенные выше результаты показывают"hello world"Предложение разделено на два слова, потому что английский язык естественно разделяется пробелами, поэтому разделять слова пробелами естественно, и в этом нет никакой проблемы.

Давайте посмотрим на пример китайского предложения.Запрос на REST выглядит следующим образом

curl -H "Content-Type: application/json" -PUT 'localhost:9200/_analyze' -d '
{  
    "text": "我爱编程"  
}' | json

После успешной операции содержание ответа выглядит следующим образом

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   383  100   348  100    35  69600   7000 --:--:-- --:--:-- --:--:-- 76600
{
  "tokens": [
    {
      "token": "我",
      "start_offset": 0,
      "end_offset": 1,
      "type": "<IDEOGRAPHIC>",
      "position": 0
    },
    {
      "token": "爱",
      "start_offset": 1,
      "end_offset": 2,
      "type": "<IDEOGRAPHIC>",
      "position": 1
    },
    {
      "token": "编",
      "start_offset": 2,
      "end_offset": 3,
      "type": "<IDEOGRAPHIC>",
      "position": 2
    },
    {
      "token": "程",
      "start_offset": 3,
      "end_offset": 4,
      "type": "<IDEOGRAPHIC>",
      "position": 3
    }
  ]
}

Из результатов видно, что этот тип сегментации слов разделяет каждый китайский иероглиф независимо, что не имеет смысла для сегментации китайских слов, поэтому устройство сегментации слов по умолчанию в ES проблематично для обработки китайского языка. К счастью, есть много хороших сторонних китайских токенизаторов, которые можно использовать в сочетании с ES. В ES каждый токенизатор (как встроенный, так и сторонний) имеет имя. Операция по умолчанию выше, имя фактического токенизатораstandard. Следующий запрос эквивалентен представленному ранее, например:

curl -H "Content-Type: application/json" -PUT 'localhost:9200/_analyze' -d '
{  
    "analyzer": "standard",
    "text": "我爱编程"  
}' | json

Когда мы меняем токенизатор для обработки сегментации слов, нам нужно только изменить"analyzer"В поле можно указать соответствующее имя токенизатора.

ES поддерживает сторонние токенизаторы путем установки плагинов.Для сторонних китайских токенизаторов чаще используются токенизаторы smartcn и IKAnanlyzer ICTCLAS Китайской академии наук.

Ниже представлен токенизатор IKAnanlyzer (далее именуемыйik) для ознакомления и использования.

установка ик токенайзера

ES предоставляет скриптelasticsearch-plugin(asticsearch-plugin.bat под windows) для установки плагина скрипт находится в каталоге bin каталога установки ES.

elasticsearch-pluginСкрипт может иметь 3 вида команд, отличающихся параметрами


// install
// 安装指定的插件到当前ES节点中。
elasticsearch-plugin install 插件地址

// list
// 显示当前ES节点已经安装的插件列表
elasticsearch-plugin list


// remove
// 删除已安装的插件
elasticsearch-plugin remove 插件名称

использоватьelasticsearch-plugin installПри установке плагина адресом плагина может быть либо адрес удаленного файла (онлайн-установка), либо файл, загруженный в локальную область. Будь то удаленный файл или локальный файл, этоzipдокумент.

Уведомление,ikверсия, чтобы соответствоватьESверсия такая же. Здесь установлена ​​версия ES 7.6.2, поэтому ik также устанавливает версию 7.6.2.

Команда удаленной установки файла выглядит следующим образом

elasticsearch-plugin  install https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v7.6.2/elasticsearch-analysis-ik-7.6.2.zip

Следует отметить, что установка локального пути под Linux.zipПри упаковке путь к файлу необходимо добавить передfile:///префикс, например

elasticsearch-plugin  install 
file:///home/hadoop/elasticsearch-analysis-ik-7.6.2.zip

После установки

  • находится в каталоге установки ESpluginsеще один в каталогеanalysis-ikкаталог (содержимоеikизzipВсе файлы в корневом каталоге после распаковки пакета, всего 5jarфайл и 1propertiesфайл конфигурации)
  • Кроме того, в каталоге установки ESconfigеще один в каталогеanalysis-ikкаталог (содержимоеikизzipПосле распаковки пакета корневой каталогconfigВсе файлы в каталоге для размещенияikпользовательский тезаурус)

Ссылаясь на онлайн-материалы, познакомит с конфигурационными файлами, которые должны быть в ES после установки плагина ik.elasticsearch.ymlДобавьте следующую строку в (/usr/local/etc/elasticsearch/elasticsearch.yml)

index.analysis.analyzer.ik.type: "ik"

Однако реальная ситуация такова, что после добавления этого предложения ES не запустится.

Это потому что,В новой версии ЕС,index.analysis.analyzer.ik.typeОн больше не нужен, и при добавлении автозагрузки будет выдано сообщение об ошибке. Версии ES 5.X больше не проходятelasitcsearch.ymlКонфигурация устанавливает правила сегментации слов, но вместо этого указывается при создании индекса.

должны знать о том,ikПосле завершения установки вам необходимо перезапустить ES, прежде чем вы сможете продолжитьikиспользовать.

Давайте представим еще одну яму, обратитесь к использованию, данному в Интернете.ikНапример, команда запроса выглядит следующим образом

curl -H "Content-Type: application/json" -PUT 'localhost:9200/_analyze' -d '
{  
    "analyzer": "ik",
    "text": "我爱编程"  
}' | json

Выполнение вышеуказанной команды всегда будет возвращать следующее сообщение об ошибке

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   264  100   207  100    57  25875   7125 --:--:-- --:--:-- --:--:-- 33000
{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "failed to find global analyzer [ik]"
      }
    ],
    "type": "illegal_argument_exception",
    "reason": "failed to find global analyzer [ik]"
  },
  "status": 400
}

Сообщение об ошибке все еще очень ясно, токенизатор не может быть найденik.

Это потому что,В новой версии ES изменилось название токенизатора, оно больше неik. Новая версия ik предоставляет два токенизатора, а именноik_max_wordиik_smart, замените либоik, нет проблем.

curl -H "Content-Type: application/json" -PUT 'localhost:9200/_analyze' -d '
{  
    "analyzer": "ik_smart",
    "text": "我爱编程"  
}' | json



  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   312  100   249  100    63  83000  21000 --:--:-- --:--:-- --:--:--  101k
{
  "tokens": [
    {
      "token": "我",
      "start_offset": 0,
      "end_offset": 1,
      "type": "CN_CHAR",
      "position": 0
    },
    {
      "token": "爱",
      "start_offset": 1,
      "end_offset": 2,
      "type": "CN_CHAR",
      "position": 1
    },
    {
      "token": "编程",
      "start_offset": 2,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 2
    }
  ]
}

Ниже приведено использованиеelasticsearch-headДемо для поиска.

Использование китайского токенизатора ik

действовать следующим образомik_max_wordиik_smartСравнение эффектов сегментации слов.

Его можно найти,Причастие китайское «Мир такой большой»,ik_max_wordСравниватьik_smartПолучите больше китайских слов, но это также создает проблему, используяik_max_wordзаймет больше места для хранения.

  • ik_max_word
curl -H "Content-Type: application/json" -PUT 'localhost:9200/_analyze' -d '
{
    "analyzer": "ik_max_word",
    "text": "世界如此之大"
}' | json

//echo

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   407  100   339  100    68  12107   2428 --:--:-- --:--:-- --:--:-- 14535
{
  "tokens": [
    {
      "token": "世界",
      "start_offset": 0,
      "end_offset": 2,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "如此之",
      "start_offset": 2,
      "end_offset": 5,
      "type": "CN_WORD",
      "position": 1
    },
    {
      "token": "如此",
      "start_offset": 2,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 2
    },
    {
      "token": "之大",
      "start_offset": 4,
      "end_offset": 6,
      "type": "CN_WORD",
      "position": 3
    }
  ]
}
  • ik_smart
curl -H "Content-Type: application/json" -PUT 'localhost:9200/_analyze' -d '
{
    "analyzer": "ik_smart",
    "text": "世界如此之大"
}' | json


//echo

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   324  100   255  100    69  51000  13800 --:--:-- --:--:-- --:--:-- 64800
{
  "tokens": [
    {
      "token": "世界",
      "start_offset": 0,
      "end_offset": 2,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "如此",
      "start_offset": 2,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 1
    },
    {
      "token": "之大",
      "start_offset": 4,
      "end_offset": 6,
      "type": "CN_WORD",
      "position": 2
    }
  ]
}

пользовательский словарь ik

Иногда сам словарь сегментации слов, предоставляемый ik, может не соответствовать некоторым специфическим требованиям (таким как специальные существительные и т. д.), ik предоставляет функцию пользовательского словаря, то есть пользователи могут сами определить некоторые слова, чтобы ik их считал. как содержимое словаря для обработки.

Например, для китайского предложения "the world is so big" в приведенном выше примере не будет такого слова "world so" в тезаурусе ik. Предполагая, что "world so" является специальным существительным, мы надеемся, что ik сможет его распознать. . . . В это время словарь ик можно настроить. Конкретный метод заключается в следующем

  1. Шаг 1: Создайте новое расширение какdicТекстовый файл, напишите записи, которые вы хотите добавить в файл, каждая запись имеет отдельную строку, например, имя файлаtest.dic, содержимое файла следующее
界如此
高潜

В приведенном выше примере есть два пользовательских термина.

  1. Шаг 2: Поместите вышеуказанноеdicфайл в каталог установки ES (/usr/local/var/homebrew/linked/elasticsearch-full)изconfigв каталогеanalysis-ikВ каталоге можно создавать подкаталоги и размещать их в подкаталогах. Например, путь к файлу/usr/local/etc/elasticsearch/analysis-ik/mydict/test.dic

  2. Шаг 3: Измените файл конфигурации ikIKAnalyzer.cfg.xml(родыconfig/analysis-ikкаталог), добавьте следующие записи в файл конфигурации

<!--用户可以在这里配置自己的扩展字典 -->
<!-- <entry key="ext_dict"></entry> -->
<entry key="ext_dict">mydict/test.dic</entry>

Это добавит файл пользовательского словаря в словарь ik.

  1. Шаг 4: Перезапустите ES, чтобы конфигурация вступила в силу. и инициировать запрос на просмотр результатов
curl -H "Content-Type: application/json" -PUT 'localhost:9200/_analyze' -d '
{
    "analyzer": "ik_max_word",
    "text": "世界如此之大"
}' | json


//echo

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   491  100   423  100    68  70500  11333 --:--:-- --:--:-- --:--:-- 81833
{
  "tokens": [
    {
      "token": "世界",
      "start_offset": 0,
      "end_offset": 2,
      "type": "CN_WORD",
      "position": 0
    },
    {
      "token": "界如此",
      "start_offset": 1,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 1
    },
    {
      "token": "如此之",
      "start_offset": 2,
      "end_offset": 5,
      "type": "CN_WORD",
      "position": 2
    },
    {
      "token": "如此",
      "start_offset": 2,
      "end_offset": 4,
      "type": "CN_WORD",
      "position": 3
    },
    {
      "token": "之大",
      "start_offset": 4,
      "end_offset": 6,
      "type": "CN_WORD",
      "position": 4
    }
  ]
}

Можно видеть, что самоопределяемая запись «мир так» была сегментирована. Но если мы будемanalyzerизменить наik_smartОднако было обнаружено, что запись «такие как эта» не может быть распознана.

Сегментация китайских слов в документах

Предыдущее введение — это просто простой пример использования ik, давайте представим сегментацию слов на более полном примере.

После создания индекса (индекса) сегментация слов ЭП может быть установлена ​​через команду REST, чтобы последующие данные, вставленные в индекс, обрабатывались соответствующим токенизатором.

Для сравненияik_smartиik_max_wordЭти два токенизатора и токенизатор по умолчаниюstandard, мы создаем 3 индекса для использования этих 3 токенизаторов соответственно.

  1. создать индекс
curl -H 'Content-Type: application/json' -X PUT 'localhost:9200/index_ik_s' |json
curl -H 'Content-Type: application/json' -X PUT 'localhost:9200/index_ik_m' |json
curl -H 'Content-Type: application/json' -X PUT 'localhost:9200/index_stan' |json
  1. установить токенизатор
curl -H "Content-Type: application/json" -PUT 'localhost:9200/index_ik_s/_mapping' -d '
{
        "properties": {
            "content": {
                "type": "text",
                "analyzer": "ik_smart",
                "search_analyzer": "ik_smart"
            }
        }
}' | json

//echo

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   220  100    21  100   199    132   1251 --:--:-- --:--:-- --:--:--  1383
{
  "acknowledged": true
}
curl -H "Content-Type: application/json" -PUT 'localhost:9200/index_ik_m/_mapping' -d '
{
        "properties": {
            "content": {
                "type": "text",
                "analyzer": "ik_max_word",
                "search_analyzer": "ik_max_word"
            }
        }
}' | json
curl -H "Content-Type: application/json" -PUT 'localhost:9200/index_stan/_mapping' -d '
{
        "properties": {
            "content": {
                "type": "text",
                "analyzer": "standard",
                "search_analyzer": "standard"
            }
        }
}' | json
  1. вставить данные

Для пакетной вставки мы используем команду linux curl для выполнения операции REST.

curl -XPOST http://localhost:9200/index_ik_s/_create/1 -H 'Content-Type:application/json' -d'
{"content":"美国留给伊拉克的是个烂摊子吗"}' |json

curl -XPOST http://localhost:9200/index_ik_s/_create/2 -H 'Content-Type:application/json' -d'
{"content":"公安部:各地校车将享最高路权"}' |json

curl -XPOST http://localhost:9200/index_ik_s/_create/3 -H 'Content-Type:application/json' -d'
{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}' |json

curl -XPOST http://localhost:9200/index_ik_s/_create/4 -H 'Content-Type:application/json' -d'
{"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}' |json
curl -XPOST http://localhost:9200/index_ik_m/_create/1 -H 'Content-Type:application/json' -d'
{"content":"美国留给伊拉克的是个烂摊子吗"}' |json

curl -XPOST http://localhost:9200/index_ik_m/_create/2 -H 'Content-Type:application/json' -d'
{"content":"公安部:各地校车将享最高路权"}' |json

curl -XPOST http://localhost:9200/index_ik_m/_create/3 -H 'Content-Type:application/json' -d'
{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}' |json

curl -XPOST http://localhost:9200/index_ik_m/_create/4 -H 'Content-Type:application/json' -d'
{"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}' |json
curl -XPOST http://localhost:9200/index_stan/_create/1 -H 'Content-Type:application/json' -d'
{"content":"美国留给伊拉克的是个烂摊子吗"}' |json

curl -XPOST http://localhost:9200/index_stan/_create/2 -H 'Content-Type:application/json' -d'
{"content":"公安部:各地校车将享最高路权"}' |json

curl -XPOST http://localhost:9200/index_stan/_create/3 -H 'Content-Type:application/json' -d'
{"content":"中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"}' |json

curl -XPOST http://localhost:9200/index_stan/_create/4 -H 'Content-Type:application/json' -d'
{"content":"中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"}' |json
  1. Пример простого запроса

Ниже приведен простой пример запроса.

curl -XPOST http://localhost:9200/index_ik_s/_search  -H 'Content-Type:application/json' -d'
{
    "query" : { "match" : { "content" : "中国" }},
    "highlight" : {
        "pre_tags" : ["<tag1>", "<tag2>"],
        "post_tags" : ["</tag1>", "</tag2>"],
        "fields" : {
            "content" : {}
        }
    }
}' |json

//echo

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   928  100   697  100   231   1671    553 --:--:-- --:--:-- --:--:--  2225
{
  "took": 413,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 2,
      "relation": "eq"
    },
    "max_score": 0.66590554,
    "hits": [
      {
        "_index": "index_ik_s",
        "_type": "_doc",
        "_id": "4",
        "_score": 0.66590554,
        "_source": {
          "content": "中国驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
        },
        "highlight": {
          "content": [
            "<tag1>中国</tag1>驻洛杉矶领事馆遭亚裔男子枪击 嫌犯已自首"
          ]
        }
      },
      {
        "_index": "index_ik_s",
        "_type": "_doc",
        "_id": "3",
        "_score": 0.61737806,
        "_source": {
          "content": "中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"
        },
        "highlight": {
          "content": [
            "中韩渔警冲突调查:韩警平均每天扣1艘<tag1>中国</tag1>渔船"
          ]
        }
      }
    ]
  }
}
  1. Тестовая проверка и сравнение

Сначала проверьте их поддержку стандартных китайских слов, запросите «Китай», три эффекта индексации одинаковы, и все они компетентны. Команда запроса выглядит следующим образом

curl -XPOST http://localhost:9200/index_ik_s/_search  -H 'Content-Type:application/json' -d'
{
    "query" : { "match" : { "content" : "中国" }},
    "highlight" : {
        "pre_tags" : ["<tag1>", "<tag2>"],
        "post_tags" : ["</tag1>", "</tag2>"],
        "fields" : {
            "content" : {}
        }
    }
}' |json

curl -XPOST http://localhost:9200/index_ik_m/_search  -H 'Content-Type:application/json' -d'
{
    "query" : { "match" : { "content" : "中国" }},
    "highlight" : {
        "pre_tags" : ["<tag1>", "<tag2>"],
        "post_tags" : ["</tag1>", "</tag2>"],
        "fields" : {
            "content" : {}
        }
    }
}' |json

curl -XPOST http://localhost:9200/index_stan/_search  -H 'Content-Type:application/json' -d'
{
    "query" : { "match" : { "content" : "中国" }},
    "highlight" : {
        "pre_tags" : ["<tag1>", "<tag2>"],
        "post_tags" : ["</tag1>", "</tag2>"],
        "fields" : {
            "content" : {}
        }
    }
}' |json

Выполните экстремальный нестандартный поиск ниже, выполните поиск по ключевому слову «средний», вы можете найти,ik_smartиik_max_wordНи один из этих двух токенизаторов не может получить результаты, токенизатор по умолчаниюstandardКонтент можно проверить. Это потому, что токенизатор по умолчаниюstandardПри поиске каждое слово будет разбито на условие поиска.

curl -XPOST http://localhost:9200/index_stan/_search  -H 'Content-Type:application/json' -d'
{
    "query" : { "match" : { "content" : "均每" }},
    "highlight" : {
        "pre_tags" : ["<tag1>", "<tag2>"],
        "post_tags" : ["</tag1>", "</tag2>"],
        "fields" : {
            "content" : {}
        }
    }
}' |json

//echo

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   672  100   442  100   230  22100  11500 --:--:-- --:--:-- --:--:-- 33600
{
  "took": 16,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 2.2112894,
    "hits": [
      {
        "_index": "index_stan",
        "_type": "_doc",
        "_id": "3",
        "_score": 2.2112894,
        "_source": {
          "content": "中韩渔警冲突调查:韩警平均每天扣1艘中国渔船"
        },
        "highlight": {
          "content": [
            "中韩渔警冲突调查:韩警平<tag1>均</tag1><tag1>每</tag1>天扣1艘中国渔船"
          ]
        }
      }
    ]
  }
}

В заключение делается эмпирический вывод.

  • ik_smartОн может не только соответствовать требованиям английского языка, но и быть умнее и легче, занимая наименьшее количество памяти, поэтому рекомендуетсяik_smart
  • standardПоддержка английского языка является лучшей, но для китайского она проста и жестока.Построить обратный индекс для каждого слова, который тратит место на диске, а эффект очень плохой.
  • ik_max_wordСравниватьik_smartПоддержка китайского языка более полная, но накладные расходы на хранилище слишком велики, не рекомендуется использовать