1. Começando com a pesquisa de texto completo
Primeiro introduza dados estruturados e não estruturados:
- Os dados estruturados definem antecipadamente as características dos dados em um formulário estruturado e os dados têm um formato fixo ou comprimento limitado. Dados estruturados típicos são a estrutura de tabela de bancos de dados relacionais tradicionais.As características dos dados são refletidas diretamente nos campos da estrutura da tabela, portanto, a recuperação de dados com base em uma determinada característica é muito direta e relativamente rápida.
- Os dados não estruturados não têm características estruturadas predefinidas, nem têm um formato fixo e comprimento fixo. Dados não estruturados típicos incluem artigos, fotos, vídeos, páginas da web, e-mails, etc. Entre eles, documentos com um determinado formato, como páginas da web em HTML, também são chamados de dados semiestruturados.
Para recuperação de dados não estruturados, ela é chamada de recuperação de texto completo.
Suponha que haja uma tabela User no MySQL, que contém três estágios: nome, idade e favor:
Para a tabela Usuário, ela é estruturada como um todo, por exemplo, nome e idade podem ser indexados diretamente para recuperação rápida.
E o campo favor é um tipo de texto, que armazena dados de texto não estruturados:
basquete, futebol, eu que adora esportes; adoro aprender e, ocasionalmente, jogar! ! ! !
Em comparação com a consulta estruturada, o maior problema enfrentado pela pesquisa de texto completo é o desempenho. O cenário de aplicação mais geral da recuperação de texto completo é localizar documentos que contenham essas palavras-chave com base em algumas palavras-chave.Por exemplo, a função de um mecanismo de pesquisa na Internet é localizar páginas da Web com base em algumas palavras-chave. Obviamente, se não houver tratamento especial para os documentos, a única forma de encontrá-los é compará-los um a um.
Supondo que você precise encontrar o usuário que contém a palavra-chave "futebol" a favor, você só pode usar como consulta difusa:
select * from user where favor like '%足球%'
A instrução like não pode ser indexada. Ao consultar, a tabela inteira será verificada e cada campo de favor será percorrido e correspondido para localizar os registros que contêm a palavra-chave "futebol". A complexidade geral é particularmente alta, portanto, a pesquisa de texto completo também é MySQL. Esse tipo de banco de dados relacional estruturado não pode atender bem aos requisitos.
A recuperação de texto completo geralmente procura registros que contenham certas ou determinadas palavras-chave, portanto, o índice estabelecido pelo valor geral do documento não ajuda a melhorar a velocidade da consulta. Para resolver esse problema, as pessoas criaram um novo método de índice, que é o índice invertido.
2. O princípio do índice invertido
O índice invertido é criado para resolver o problema de recuperação dos dados não estruturados mencionados acima.
Primeiramente, vamos deixar claro que a unidade de armazenamento dos registros no ES é o "documento" JSON, e os "campos" no "documento" JSON são os pares KV que compõem o JSON.
Índices comuns também são chamados de índices de encaminhamento, ou seja, indexando chaves primárias e campos estruturados, os documentos podem ser encontrados por meio desses índices estruturados.
O índice invertido primeiro extrai todas as palavras-chave contidas no documento, depois salva a relação correspondente entre as palavras-chave e o documento e, finalmente, classifica as próprias palavras-chave. Ao recuperar uma determinada palavra-chave, o usuário pode primeiro pesquisar o índice da palavra-chave e, em seguida, localizar o documento por meio do relacionamento correspondente entre a palavra-chave e o documento.
Assumindo que a tabela do usuário acima é armazenada pelo ES, os dois documentos do usuário são:
{
"_id: 1,
"name":"pbr1",
"age":22,
"favor":"篮球、足球、爱运动的我;本人热爱学习,游戏偶尔也玩!!!!"
}
{
"_id: 2,
"name":"pbr2",
"age":22,
"favor":"篮球、足球、爱运动的我"
}
Dentre eles, favor é definido como o tipo de texto, assumindo que o tokenizer realiza a seguinte segmentação de palavras:
- Favor particípio do documento 1: "Basquete", "Futebol", "Adoro esportes", "Adoro aprender", "Também jogo ocasionalmente" esses 5 tokens
- Favor particípio do documento 2: três tokens: "basquetebol", "futebol" e "eu amo esportes"
Em seguida, indexe o token de segmentação de palavras e estabeleça um mapeamento para o documento original para obter um índice invertido para segmentação de palavras a favor:
Pode-se ver que o índice invertido é, na verdade, um processo de estruturação dos dados de texto completo. Para dados armazenados em bancos de dados relacionais, eles contam com a pré-análise humana para desmontar os dados em diferentes campos, de modo que os dados já estejam estruturados quando inseridos; enquanto em bancos de dados de texto completo, os documentos ainda não são estruturados e requerem o aplicativo para extrair palavras-chave automaticamente de acordo com as regras e formar uma correspondência estruturada entre palavras-chave e documentos.
Por exemplo, agora você precisa consultar os usuários cujos hobbies são "basquete" e "futebol", então você pode obter diretamente o documento 1 e o documento 2 correspondentes por meio do índice invertido e pode consultar esses dois usuários.
3. Processo de construção do índice ES
A extração de palavras-chave na pesquisa de texto completo é uma etapa muito importante. Essas palavras-chave pré-extraídas são geralmente chamadas de termos no Elasticsearch e na literatura relacionada à recuperação de texto completo.O termo extração de documentos é chamado de análise de documento no Elasticsearch, que é o núcleo de todo o processo de recuperação de texto completo. Este processo tem que distinguir quais são termos e quais não são. Para o inglês, também é preciso saber que apple e apples referem-se à mesma coisa, e run e running referem-se à mesma ação. É ainda mais problemático para o chinês, porque as palavras chinesas não são separadas por espaços, então o primeiro problema é como distinguir as palavras.
A camada inferior do ES usa Lucene para construir o índice. Um processo básico é segmentar o campo do tipo de texto primeiro. O segmentador de palavras usado para segmentação de palavras é baseado naquele especificado ao configurar o mapeamento. O segmentador de palavras padrão é usado por padrão. Para segmentação de palavras chinesas, geralmente é recomendado usar tokenizer ik_smart ou ik_max_word:
Você pode aprender este artigo sobre como o Lucene armazena esses resultados da análise de segmentação de palavras: https://www.shenyanchao.cn/blog/2018/12/04/lucene-index-files/
Como o processo de análise e indexação antes do armazenamento de documentos é intensivo em recursos, para melhorar o desempenho, os documentos não são indexados imediatamente quando são adicionados ao ES.
Por padrão, o ES processará uniformemente os documentos recém-adicionados a cada 1s, que podem ser modificados por meio do parâmetro index.refresh_interval.
Para melhorar o desempenho, o parâmetro index.search.idle.after também é adicionado no ES 7. Seu valor padrão é 30s: se o índice não receber uma solicitação de recuperação de dados por um período de tempo, ele aguardará pelo menos 30s antes Atualizar dados de índice.
Portanto, pode-se ver que a operação de gravação do ES é quase em tempo real e os documentos recém-adicionados ao índice podem não ser recuperados por um período de tempo. Se você realmente precisar recuperar os documentos imediatamente, poderá usar o método de atualização forçada para o índice, incluindo Use a interface _refresh e use o parâmetro de atualização ao operar o documento para forçar a atualização do índice no buffer para o disco.