Эта статья не включает в себя конкретные принципы Elasticsearch, но записывает только то, как быстро импортировать данные в MySQL для полнотекстового поиска.
На работе вам необходимо внедрить функцию поиска и импортировать существующие данные базы данных. Лидер команды рекомендует использовать Elasticsearch для его реализации. Вы можете искать учебники в Интернете, которые являются относительно старыми статьями. У меня нет выбора, кроме как исследовать это сам. Обратитесь к документации ES и, наконец, создайте услугу. Я запишу это. Я надеюсь, что друзья с одинаковыми потребностями могут избежать обхода и быстро создать доступную услугу Elasticsearch в соответствии с этим учебником.
ES Construction
ES Builds может напрямую загружать файлы ZIP и контейнеры Docker. Относительно говоря, Docker более подходит для нас для запуска услуг ES. Можно легко создать кластер или создать тестовую среду. Метод контейнера также используется здесь. Во -первых, нам нужен Dockerfile:
От docker.elastic.co/elasticsearch/elasticsearch-oss:6.0.0# Отправить конфигурацию. Включите новую Elasticsearch.yml и Keystore.jks copy-chown = elasticsearch: Elasticsearch Conf//usr/share/elasticsearch/config/# install Ikrun ./bin/elasticsearch-plugin install Install Install Install. https://github.com/medcl/elasticsearch-analysis-ik/releases/download/v6.0.0/elasticsearch-analysis-ik-6.0.0.zip# Установить readonlestres https://github.com/hyy-yu/beziercurvedemo/raw/master/readonlyrest-1.16.14_es6.0.0.zipuser elasticsearchcmd ./bin/elasticsearch
Вот объяснение приведенной выше операции:
Эликтическая конфигурация Elasticsearch.yml
cluster.name: "docker-cluster" network.host: 0.0.0.0# minimum_master_nodes должен быть явно устанавливается, когда связано с общедоступным IP# для 1, чтобы разрешить однозначные кластеры# Подробности: https://github.com/elastic/elasticsearch/pull/1728888888888888888888888 гг. Exchange Memory On ES bootstrap.memory_lock: true http.type: ssl_netty4readonlyrest: enable: true ssl: enable: inving keystore_file: "server.jks" keystore_pass: server key_pass: server access_control_rules: - name: "block 1 -type: type: type: addrin addrine:" anderment: "ander:" upport ":" anderment: " Индексы: ["Paper*"] Действия: ["Индексы: data/read/*"] Пользователи: - Имя пользователя: root auth_key_sha256: CB7C98BAE153065DB931980A13BD45EE3A77CB8F27A7DFEE68F686377AC33F1: admamer: admaMERMAMER: auth_key: Xiaoming: xiaming Groups: [«Пользователь»]
Здесь bootstrap.memory_lock: True - это яма, запрещающая обмен памяти. Документ уже объяснил, что некоторая ОС будет временно поменяться неиспользованной памятью в область жесткого диска во время выполнения. Тем не менее, это поведение взлетит скорость использования ресурсов ES и даже сделает систему неспособной ответить.
В файле конфигурации уже очевидно, что root -пользователь принадлежит группе администратора, а у администрации есть все разрешения. Поскольку Xiaming находится в группе пользователей, он может получить доступ только к индексу бумаги и может только читать, но не может работать. Для получения более подробной конфигурации см.: Документация READONLYREST
На этом этапе подготовка к ES была завершена. Docker Build -T ESIMAGE: TAG. Docker Run -p 9200: 9200 Esimage: Tag Run.
Если https://127.0.0.1:9200/ Возвращение
{"name": "vakwrir", "cluster_name": "docker-cluster", "cluster_uuid": "ysydowkvrh2swz907s2m_w", "версия": {"№": "6.0.0", "build_hash": "8f0685b", "build_date": " «2017-11-10T18: 41: 22,859Z», «build_snapshot»: false, "lucene_version": "7.0.1", "minimum_wire_compatibility_version": "5.6.0", "minimum_index_compatibility_version": "5.0.0"}, "you weark_compatibility_version": "5.0.0.Главный герой нашего урока появился. Я поделюсь несколькими часто используемыми API, чтобы дразнить и отлаживать:
{{url}} заменяется вашим локальным адресом ES.
Импортируйте данные MySQL
Я использую здесь данные MySQL, но на самом деле другие базы данных одинаковы. Ключ в том, как импортировать. Онлайн-учебник порекомендует плагин MySQL для LogStash, Beat и ES для импорта. Я также попробовал это. Конфигурация громоздкая, а документы редки. Если структура базы данных немного сложна, импорт является трудоемкой задачей, поэтому она не рекомендуется. На самом деле, ES имеет соответствующие библиотеки API на каждом языке. Вы можете собрать данные в JSON на языковом уровне и отправить их в ES через библиотеку API. Процесс примерно следующим образом:
Я использую библиотеку Golang ES Elastic. Вы можете искать на GitHub для других языков, а метод работы такой же.
Далее, используйте простую базу данных, чтобы ввести ее:
Бумажный стол
| идентификатор | имя |
|---|---|
| 1 | Пекин № 1 моделирование начальной школы |
| 2 | Jiangxi pecijin |
Провинция таблица
| идентификатор | имя |
|---|---|
| 1 | Пекин |
| 2 | Цзянси |
Paper_province Table
| paper_id | Province_id |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 2 | 2 |
Как упоминалось выше, бумага и провинция являются отношениями от многих ко многим. Теперь эти бумажные данные введены в ES, вы можете нечетко искать имени бумаги или фильтровать через провинцию. Формат данных JSON выглядит следующим образом:
{"id": 1, "name": "Пекин № 1 Том моделирования начальной школы", "Провинции": [{"ID": 1, "Имя": "Пекин"}]} Сначала подготовьте файл mapping.json, который является определением структуры хранилища данных в ES.
{"mappings": {"docs": {"include_in_all": false, "свойства": {"id": {"type": "long"}, "name": {"type": "text", "Analyzer": "IK_MAX_WORD" // Использование Партератора Word}, "Провидцы": ":" (ntavies ":" hyEert " «id»: {"type": "integer"}, "name": {"type": "text", "index": "false" // не индексировать}}}}}}}}}}}}, "Настройки": {"number_shards": 1, "number_f_replicas"Следует отметить, что поле _all отменено. Этот по умолчанию _all собирает все поля хранения для достижения безусловного ограниченного поиска. Недостатком является то, что пространство много занимает.
Я установил номер Shard на 1, и реплики не установлены. В конце концов, это не кластер, а обработка данных не так много. Если есть большое количество данных, которые необходимо обработать, вы можете установить количество осколков и реплик самостоятельно.
Во-первых, установите связь с ES, CA.CRT связана с самосознанием JKS. Конечно, здесь я использую Insecureskipverify, чтобы игнорировать проверку файла сертификата.
func initelasticsearch () {pool: = x509.newcertpool () crt, err0: = ioutil.readfile ("conf/ca.crt") if err0! &tls.Config{RootCAs: pool, InsecureSkipVerify: true}, } httpClient := &http.Client{Transport: tr} //Background construct elasticClient var err error elasticClient, err = elastic.NewClient(elastic.SetURL(MyConfig.ElasticUrl), elastic.SetErrorLog(GetLogger()), Elastic.SetGzip (true), Elastic.SethttpClient (httpclient), Elastic.setsniff (false), // Cluster Sniff, не забудьте закрыть один узел. "search_client_error") return} // ElasticClient завершена // Запрос, существует ли бумажный индекс, err: = elasticclient.indexexists (myConfig.elasticIndexname) .do (context.background ()), если err! отправлено, если существует {if! Isindexintegrity (ElasticClient) {// Удалить текущий индекс и подготовиться к восстановлению DeleTerSponse, err: = elasticClient.deleteIndex (myConfig.elasticIndexname) .do (context.background ()) Если ошибка! = nil || ! DeleterSponse.acknowgedged {непредооооооооооопен (err, "delete_index_error") return}} else {return}} // База данных фонового запроса и отправить данные в ElasticSearch go fetchDbgetAllpaper andSendToes ()} Тип Paperearch struct {paperid int64 `gorm:" primary_key; column: f_paper_id; type: bigint (20) "json:" id "` name string `gorm:" column: f_name; size: 80 "json:" name "` provinces [] Province `gorm:" mysome2my: t_paper_province; " JSON: "Провинции" // провинции, для которых применима тестовая статья} fuckDbgetallpaperandsendtoes () {// Извлекать бумагу var allpply [] papersearch getDb (). Таблица ("t_papers"). GetDB (). Table ("t_provinces"). Joins («Внутреннее соединение` t_paper_province` на `t_paper_province`. Allpaper [i] .paperid) .find (& allpro) Allpaper [i] .provinces = allpro} if len (allpaper)> 0 {// отправить в ES - Create Index createService: = getElasticsearch (). CreateIndex (myConfig.elasticIndExname) // Индекс_default_setting здесь - это контент. CreateService.Body (index_default_setting) createresult, err: = createService.do (context.background ()), если ошибки! // - Отправить все бумаги Bulkrequest: = getElasticsearch (). Bulk () для i: = ляп -allape {indexReq: = elastic.newbulkindexRequest (). Doc (allpaper [i]) bulkrequest.add (indexReq)} // Do отправляет объемные запросы на ElasticSearch Bulkresponse, err: = bulkrequest.do (context.background ()), если ошибки! Len (bulkresponse.created ())! = Len (Allpaper) {непредооооооооооопен (err, "insert_docs_nums_error") return} // Отправить успех}} После выполнения приведенного выше кода используйте {{url}}/_ CAT/Индексы? V, чтобы увидеть, появится ли недавно созданный индекс, и использовать {{url}}/papers/_search, чтобы увидеть, сколько документов попало. Если количество документов равно количеству данных, которые вы отправили в прошлом, служба поиска будет рассматриваться.
поиск
Теперь вы можете искать тестовые документы провинции и Q, а по умолчанию отсортируется по оценке актуальности.
// Q Search String String Provinceid Limited Province ID Limit Limit Page Paremant Paraments Parameters поиск (Q String, Provinceid Uint, Limit Int, Page Int) (List [] PaperSearch, TotalPage int, CurrentPage int, pageIsend int, returnerR Error) {// Если условия не выполнены, используйте DataBase для поиска! Searchpaperlocal (Q, CourseID, GradeID, ProvinceID, PaperTyPeid, Limit, Page)} List = Make ([] PapersImple, 0) TotalPage = 0 CurrentPage = Page PageIsend = 0 returner = nil client: = getElasticsearch () if client == nil {return searchlocal (q, courceid, gradeId, provinceid, papetyd, particyd, limityd) Проблема с Elasticsearch, используйте базу данных для поиска, если! Isindexintegrity (Client) {return Searchpaperlocal (Q, CourseId, GradeId, Provinceid, Papertypeid, Limit, Page)} if! Client.isrunning () {client.Start ()} defer.stop () q = html.escapestring (q) quoLquer Elastic.newboolquery () // paper.name matchquery: = elastic.newmatchquery ("name", q) // province if provinceid> 0 && provinceid! = default_province_all {provool: = elastic.newboolquery () tpro: = elastic.newtermquery ("virindceded" vinestedced () tpro: = elastic.newtermquery ("provinces.id" vinestsideid vinesc Elastic.newnestEdquery ("provinces", prolool.must (tpro)) boolquery.must (provest)} boolquery.must (matchquery) для _, e: = range termquerys {boolquery.must (e)} highttt: = elastic.newhighlight () allastic_sairt_sair hight.pretags (elastic_search_search_field_tag_start) hight.posttags (elastic_search_search_field_tag_end) searchresult, err2: = client.search (myconfig.elasticindexname). Выделение (Highligt). Запрос (Boolquery). От ((Page - 1) * Limit). Размер (предел). Do (context.background ()) if err2! = Nil {// Ошибка обработки getLogger (). Logerr («Произошла ошибка во время поиска"+err2.error (), "search_error") // Ошибка обработки returnerr = errors.new ("Ошибка произошла во время поиска")} else {ifsresult.hits.totalhits> 0 {//thate через rase resports {// ithate straint straints {//thate straint straint straint straints {//thate через rance -ressorsult.hits.totalhits> 0 searchresult.hits.hits {var p papersearch err: = json.unmarshal (*hit.source, & p), если ошибка! len (hit.highlight [elastic_search_search_field_name])> 0 {p.name = hit.highlight [elastic_search_search_field_name] [0]} list = append (list, p)} count: = searchresult.totalhits () currentpage = page count> 0 {totalpage = int (math.ce.ce. float64 (Limit)))} if CurrentPage> = totalPage {pageIsend = 1}} else {// no Hits}} return}Выше всего содержание этой статьи. Я надеюсь, что это будет полезно для каждого обучения, и я надеюсь, что все будут поддерживать Wulin.com больше.