Este artigo não envolve os princípios específicos do Elasticsearch, mas apenas registra como importar rapidamente dados no MySQL para pesquisa de texto completo.
No trabalho, você precisa implementar uma função de pesquisa e importar dados de banco de dados existentes. O líder da equipe recomenda o uso do Elasticsearch para implementá -lo. Você pode pesquisar nos tutoriais on -line, que são artigos relativamente antigos. Não tenho escolha a não ser explorá -lo sozinho. Consulte a documentação do ES e finalmente construa o serviço. Vou gravar. Espero que amigos com as mesmas necessidades possam evitar desvios e possam criar rapidamente um serviço de pesquisa de elasticidade disponível de acordo com este tutorial.
Es construção
O ES Builds pode baixar diretamente arquivos ZIP e contêineres do Docker. Relativamente falando, o Docker é mais adequado para executarmos os serviços ES. É possível criar um cluster facilmente ou criar um ambiente de teste. O método do contêiner também é usado aqui. Primeiro, precisamos de um Dockerfile:
De Docker.elastic.co/ellasticsearch/elticsearch-oss:6.0.0# A configuração de envio inclui os novos arquivos Elasticsearch.yml e keystore.jks copy --chown = Elasticsearch: Elasticsearch conf/usr/sharticearch/config/# install ikrun ./bin/binicsics/usr/sharticearch/config/# instalar ikrun ./bin/binicsics/usr/sharticearch/config/## https://github.com/medcl/elasticsearch-analysis https://github.com/hyy-yu/beziercurvedemo/raw/master/readonlyrest-1.16.14_es6.0.0.zipuser Elasticsearchcmd ./bin/elasticsearch
Aqui está uma explicação da operação acima:
Configuração elictica Elasticsearch.yml
cluster.name: "docker-cluster"network.host: 0.0.0.0# minimum_master_nodes need to be explicitly set when bound on a public IP# set to 1 to allow single node clusters# Details: https://github.com/elastic/elasticsearch/pull/17288discovery.zen.minimum_master_nodes: 1# Forbid the system to exchange Memória em ES bootstrap.memory_lock: true http.type: ssl_netty4readonLyrest: Ativar: true ssl: enable: true keystore_file: "servidor.jks" "Block 1 - ROOT_PASS: TIPA: TIPA_PASS: servidor Access_control_rules: - Nome" "1 - ROOTE_PASS" "TIPO: TIPO: ["Usuário"] índices: ["Paper*"] Ações: ["Indices: Data/Read/* Xiaoming Auth_Key: Xiaoming: Xiaoming Grupos: ["Usuário"]
Aqui bootstrap.memory_lock: true é um poço, proibindo a troca de memória. O documento já explicou que alguns sistemas operacionais trocarão a memória não utilizada temporariamente por uma área do disco rígido durante o tempo de execução. No entanto, esse comportamento aumentará a taxa de utilização de recursos de ES e até tornará o sistema incapaz de responder.
Já é óbvio no arquivo de configuração que um usuário root pertence ao grupo de administração, e o administrador tem todas as permissões. Como o Xiaoming está no grupo de usuários, ele só pode acessar o índice de papel e só pode ler, mas não pode operar. Para uma configuração mais detalhada, consulte: Documentação READONLYREST
Neste ponto, os preparativos para ES foram concluídos. Docker Build -t Esimage: TAG. Docker Run -P 9200: 9200 ESIMAGE: TAG RUN.
Se https://127.0.0.1:9200/ retornar
{ "name": "VaKwrIR", "cluster_name": "docker-cluster", "cluster_uuid": "YsYdOWKvRh2swz907s2m_w", "version": { "number": "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_comline:"O protagonista do nosso tutorial apareceu. Vou compartilhar várias APIs comumente usadas para provocar e depurar:
{{url}} é substituído pelo endereço ES do ES local.
Importar dados MySQL
Estou usando dados MySQL aqui, mas, de fato, outros bancos de dados são os mesmos. A chave é como importar. O tutorial on-line recomendará o plug-in MySQL para Logstash, Beat e ES para importação. Eu também tentei. A configuração é complicada e os documentos são escassos. Se a estrutura do banco de dados for um pouco complicada, a importação é uma tarefa trabalhosa, por isso não é recomendada. De fato, o ES possui bibliotecas de API correspondentes em cada idioma. Você pode montar os dados no JSON no nível do idioma e enviá -los para ES através da biblioteca da API. O processo é aproximadamente o seguinte:
Eu uso elástico da biblioteca ES de Golang. Você pode pesquisar no GitHub outros idiomas, e o método de operação é o mesmo.
Em seguida, use um banco de dados simples para apresentá -lo:
Mesa de papel
| eu ia | nome |
|---|---|
| 1 | Simulação da Escola Primária de Pequim No. 1 |
| 2 | Jiangxi Beijing General College Entrance Exame Perguntas |
Tabela de província
| eu ia | nome |
|---|---|
| 1 | Pequim |
| 2 | Jiangxi |
Tabela de Paper_province
| paper_id | Província_id |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 2 | 2 |
Como mencionado acima, o artigo e a província são relacionamentos muitos para muitos. Agora que os dados do papel são inseridos no ES, você pode pesquisar difundida pelo nome do papel ou filtrar através da província. O formato de dados JSON é o seguinte:
{"Id": 1, "Nome": "Pequim No. 1 Volume de simulação da escola primária", "Províncias": [{"Id": 1, "Nome": "Pequim"}]} Primeiro, prepare um arquivo Mapping.json, que é a definição da estrutura de armazenamento de dados no ES.
{"mappings": {"docs": {"incluir_in_all": false, "Propriedades": {"id": {"type": "long"}, "name": {"type": "text", "analzer": "ik_max_word" // use a maior palavra ": parterator" "pronuncies": "provinctes" "provinctes": "provinctes": "provinctes" ":" provinctes ":" ik_max_word "// use a maior palavra": "parterator" ":" provincuras ":" provinctes "": "provincuras": "provinctes": "ik_max_word" // usa a maior palavra ":" parterator "": "provinctes" ":" provinctes ":" ik_max_word "// use a maior palavra": "id": {"type": "integer"}, "nome": {"type": "text", "index": "false" // não indexado}}}}}}}}}}}}}}}, "configurações": {"number_of_shards": 1, "number_3.Deve -se notar que o campo _ll é cancelado. Esse _All _All coletará todos os campos de armazenamento para obter pesquisa restrita incondicional. A desvantagem é que o espaço ocupa muito.
Defino o número do Shard como 1 e nenhuma réplica está definida. Afinal, este não é um cluster e os dados processados não são muito. Se houver uma grande quantidade de dados que precisam ser processados, você poderá definir o número de fragmentos e réplicas sozinho.
Primeiro, estabeleça uma conexão com o ES, o CA.CRT está relacionado à auto-inscrição do JKS. Obviamente, aqui estou usando o InsecursKipVerify para ignorar a verificação do arquivo de certificado.
func initelasticsearch () {pool: = x509.NewCertpool () Crt, err0: = ioutil.readfile ("conf/ca.crt") se err0! = nil {não podepenenes (err0, "leia o arquivo crt err") return} pool.ApnConsTerSFROM (CRT): &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), elástico.SethttpClient (httpClient), elástico.SetSniff (false), // Snift de cluster, lembre -se de fechar um único nó. "Search_client_error") return} // A construção de client Elastic está concluída // consulta se existe um índice de papel, err: = elasticclient.indexists (myConfig.elastIndexName). se existir {if! isIndexintegrity (elasticclient) {// exclua o índice atual e prepare -se para reconstruir a resposta de deleter, err: = elasticclient.deleteIndex (myconfig.elasticsIndexname) .do (context.background ()) se err! = nil | ! DeLeteresponse.ackNowledDed {não é possível (err, "delete_index_error") return}} else {return}} // banco de dados de consulta em segundo plano e envia dados para elasticsearch go fetchdbgetAllpaperAndSendtoes ()} Digite artigos de pesquisa {paperId Int64 `gorm:" primary_key; coluna: f_paper_id; type: bigint (20) "json:" id "` name string `gorm:" coluna: f_name; tamanho: 80 "json:" name "` província [] província; JSON: "Províncias" `// Províncias para as quais o papel de teste é aplicável} functbetDbgetAllpaperAndSendtoes () {// buscar papel var allaper [] papersearch getdb (). tabela (" t_papers "). encontre (e all) // província para i: = all all) Getdb (). Tabela ("t_provipes"). AllPaper [i] .PaperId) .Find (& AllPro) Allpaper [i] .Provinces = AllPro} Se Len (Allpaper)> 0 {// Send para ES - Create Index CreateService: = Getelasticsearch (). createService.body (index_default_setting) Createresult, err: = CreateService.do (context.background ()) se err! = nil {não pode -se (err, "create_paper_index") return} se! createresult.acknowled ||! Envie todo o papel da massa de papel: = getelsticSearch (). Doc (allpaper [i]) bulkrequest.add (indexreq)} // envia as solicitações em massa para elasticsearcharch BulkResponse, err: = bulkrequest.do (context.background ()) se err! Len (allpaper) {não pode -se (err, "insert_docs_nums_error") return} // enviar sucesso}} Depois de executar o código acima, use {{url}}/_ Cat/índices? V para ver se o índice recém -criado aparece no ES e use {{url}}/papers/_search para ver quantos documentos atingem. Se o número de documentos for igual à quantidade de dados enviados no passado, o serviço de pesquisa será considerado em execução.
procurar
Agora você pode procurar documentos de teste por Província e Q, e o padrão é classificado pela pontuação de relevância.
// q Search String ProvinceID Limited Província ID Limite Página Parâmetros de paginação Func Paper (Q String, Província UINT, Limit Int, Page Int) (List [] Papersearch, TotalPage int, CurrentPage Int, PageIsend Int, ReturnticsertSicsicSearch &/ Se as condições não forem atendidas, use o DataBase para pesquisar se! CourseId, graveID, ProvinceID, PaperTypeid, Limit, Page)} List = Make ([] PapersImple, 0) TotalPage = 0 CurrentPage = Page PageIsend = 0 ReturnErr = Nil Client: = GetElSticsearch () se o cliente, o que é o que é o que é o que é o que é o que é o que é o que é o que é o que é um banco de dados para pesquisar se! isIndexintegrity (client) {return SearchPaperlocal (q, curso de curso, graveid, província, papertypeid, limite, página)} se! client.isrunning () {client.start ()} difer client.stop () q = html.escapesting (q) boolquery: : = elástico.NewMatchQuery ("Nome", q) // Província se Província> 0 && ProvinceId! = Default_province_all {ProBool: = elastic.newBoolQuery () tPro: = Elastic.NewterMQuery ("Provinces.id", Província) projeta: = Elastic.NeNeNeNey (província ", proveriveriDer (elastic.NeestQuery (província", proveriveriDer () tPro: = elastic.nestterQuery ("Provinces.id", província) projeta: = elastic.NeNeNENED.NestQuery (província ", proveriveriDer (elastic.NeestQuery (província) (província). boolQuery.must (pronest)} boolQuery.must (matchQuery) para _, e: = range termQuerys {boolquery.must (e)} destactt: = elastic.newhighlight () destacar (elastic_search_search_field_field_name) Highlight.pregs () destacar (elastic_search_search_field_field_name) Highlight._sastht () Destaque.Posttags (ELASTIC_SEARCH_SECH_FIELD_TAG_END) SearchResult, err2: = client.search (myconfig.elastindexname). Destaque (Highligt). Consulta (Boolquery). De ((página - 1) * limite). Tamanho (limite). Do (context.background ()) se err2! = Nil {// manipulam erro getLogger (). Logerr ("Ocorreu o erro ao pesquisar"+err2.error (), "search_error") // lidera o erro returrErr = errors.new ("erro ocorreu durante a pesquisa")} {if iSearret.hits.Tottalhits> SearchResult.hits.hits {var P PaPersearch err: = json.unmarshal (*hit.source, & p) se err! = nil {// Deserialização falhou getLogger (). len (hit.highlight [elastic_search_search_field_name])> 0 {p.name = hit.highlight [elastic_search_search_field_name] [0]} list = Append (list, p)} contagem: = searchResult.totAlHits () currentPage = se count 40 {totalpage: fotalpage: = searchResult.totAlhits () currentPage = se count> 0 {totalpage float64 (limite)))} se currentpage> = totalpage {PageIsend = 1}} else {// no hits}} return}O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.