Notas de estudo do ElasticSearch - Capítulo 5 Explicação detalhada da análise de documentos ES

Análise de cinco documentos

No Elasticsearch, o conteúdo do texto do documento é analisado por meio de um analisador, e o conteúdo do texto é segmentado e padronizado, processo denominado análise de documento .

5.1 O que é um analisador?

No Elasticsearch, o analisador é um módulo de software responsável principalmente por duas funções: Tokenização (segmentação de palavras) e Normalização (normalização).

  • Tokenização

    A tokenização, ou seja, tokenização, é o processo de divisão de sentenças em palavras individuais e segue certas regras.

  • Normalização

    Normalização, ou seja, normalização é o processo de processamento, conversão, modificação e enriquecimento de segmentos de palavras (palavras) na forma de lematização , sinônimos , palavras irrelevantes e outros recursos .

O analisador consiste em um tokenizer , zero ou mais filtros de caracteres e zero ou mais filtros de token. Sua estrutura é mostrada na figura abaixo.

Insira a descrição da imagem aqui

  • filtro de caracteres

    Processa o conteúdo do texto de entrada, aplicado ao nível do caractere.

  • tokenizador

    O fluxo de caracteres processado pelo filtro de caracteres é posteriormente processado e o texto é dividido em vários termos de acordo com as regras.

  • filtro de termo

    Os termos segmentados pelo tokenizer são processados ​​posteriormente.

Filtros de caracteres, tokenizadores e filtros de termos serão apresentados em detalhes nos capítulos subsequentes.

  • O processo geral de trabalho do analisador
    1. O conteúdo do texto deve primeiro ser filtrado e processado pelo filtro de caracteres
    2. O segmentador de palavras processa o conteúdo do texto processado na primeira etapa de acordo com as regras especificadas e o divide em vários termos.
    3. Processe ainda mais os termos divididos na segunda etapa
    4. Adicione os termos processados ​​na terceira etapa ao índice invertido.

5.2 Filtro de caracteres

5.2.1 Função

Os filtros de caracteres são aplicados no nível do caractere e cada caractere do texto passa por esses filtros em ordem. Esses filtros podem executar as seguintes funções específicas:

  • Remova caracteres indesejados do fluxo de entrada

    Por exemplo, você pode limpar do texto de entrada

    , e outras tags HTML.

  • Adicionar ou substituir outros caracteres em um stream existente

    Por exemplo, as letras gregas são substituídas por palavras inglesas equivalentes (0 e 1 são substituídos por falso e verdadeiro).

O Elasticsearch fornece três filtros de caracteres que podemos usar para construir nossos próprios analisadores personalizados.

5.2.2 filtro de caracteres html_strip

  • efeito

    O filtro de caracteres html_strip remove elementos HTML como e decodifica entidades HTML como &.

  • Exemplo

    Use o filtro de caracteres html_strip para processar o seguinte texto

    <h1>html_strip & test hellow</h1>
    

    Após o texto passar por esse filtro de caracteres, apenas o texto "html_strip & test hellow" permanece. Podemos enviar solicitações get/post para http://localhost:9200/_analyze e adicionar os seguintes parâmetros ao corpo da solicitação

    {
          
          
        "text":"<h1>html_strip & test hellow</h1>", // 要解析的文本内容
        "tokenizer": "standard",                   // 使用的分词器是标准分词器,后面小节会进行讲解
        "char_filter": ["html_strip"]               // 使用的字符过滤器
    }
    

    Os resultados podem ser obtidos da seguinte forma:

    Insira a descrição da imagem aqui

    // 返回值
    {
          
          
        "tokens": [
            {
          
          
                "token": "html_strip",
                "start_offset": 4,
                "end_offset": 14,
                "type": "<ALPHANUM>",
                "position": 0
            },
            {
          
          
                "token": "test",
                "start_offset": 17,
                "end_offset": 21,
                "type": "<ALPHANUM>",
                "position": 1
            },
            {
          
          
                "token": "hellow",
                "start_offset": 22,
                "end_offset": 28,
                "type": "<ALPHANUM>",
                "position": 2
            }
        ]
    }
    

    Como você pode ver no valor de retorno acima, após ser processado pelo filtro de caracteres html_strip e pelo segmentador de palavras padrão, o Elasticsearch divide o conteúdo do texto de entrada em três palavras e os elementos HTML foram removidos dele.

    O tokenizer padrão dividirá o conteúdo do texto de acordo com palavras individuais e ignorará alguns caracteres especiais, como &, que serão explicados posteriormente.

  • Mantenha alguns elementos HTML

    Usar o filtro de caracteres html_strip removerá todos os elementos HTML do conteúdo do texto. Ao mesmo tempo, o filtro de caracteres html_strip suporta a retenção de alguns elementos HTML. Podemos usar o atributo estendido escaped_tags do filtro de caracteres html_strip para especificar os elementos HTML que precisam ser retidos.

    Por exemplo, inserimos o seguinte texto

    <pre><h1>html_strip & test hellow</h1></pre>
    

    Queremos que o seguinte texto permaneça após passar pelo filtro de caracteres html_strip

    <pre>html_strip & test hellow</pre>
    

    Neste momento, não podemos mais simplesmente usar o filtro de caracteres html_strip, precisamos customizar um analisador. ( Cada parâmetro será explicado em detalhes posteriormente, aqui nos concentramos principalmente no atributo estendido escaped_tags do filtro de caracteres html_strip )

    Crie um índice usando um analisador personalizado

    // PUT http://localhost:9200/character-filter-test
    // body内容
    {
          
          
    	"settings": {
          
          
    		"analysis": {
          
          
    			"analyzer": {
          
           // 当前索引中的分析器集合
    				"test_html_strip_filter_analyzer": {
          
             // 自定义的分析器名称
    					"tokenizer": "keyword",
    					"char_filter": ["my_html_strip_filter"]  // 自定义的分析器使用的字符过滤器集合
    				}
    			},
    			"char_filter": {
          
            // 当前索引中的字符过滤器集合
    				"my_html_strip_filter": {
          
           // 自定义字符过滤器的名称
    					"type": "html_strip",  // 字符过滤器类型为html_strip
    					"escaped_tags": ["pre"]  // 要保留的html元素名
    				}
    			}
    		}
    	}
    }
    

    Analise texto usando um analisador personalizado

    // POST http://localhost:9200/character-filter-test/_analyze
    // body内容
    {
        "text":"<pre><h1>html_strip & test hellow</h1></pre>", // 要分析的文本内容
        "analyzer": "test_html_strip_filter_analyzer"  // 使用的分析器名称
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

    Como pode ser visto nos resultados, não há tag h1 no resultado após a segmentação de palavras, mas há uma tag pré.

    Observação: os resultados aqui contêm &. Isso ocorre porque o tokenizer em nosso analisador usa palavras-chave. Isso será apresentado em detalhes posteriormente. O foco aqui é apenas manter a tag pré.

5.2.3 mapeamento de filtro de caracteres

  • efeito

    O filtro de caracteres de mapeamento substitui qualquer ocorrência da sequência especificada pela sequência de substituição especificada.

  • Exemplo

    Substitua “CN” no conteúdo do texto inserido por “China”.

    // POST http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I come from CN",
        "tokenizer": "keyword", 
        "char_filter": [{
          
          
            "type":"mapping",
            "mappings":[
                "CN => 中国"
            ]
        }]
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

    Você pode ver que CN no conteúdo foi substituído pela China

  • Use um analisador personalizado

    No uso formal, geralmente é usado em conjunto com um analisador personalizado.

    Crie índice com filtro de caracteres de mapeamento personalizado

    // PUT http://localhost:9200/mapping-filter-test
    // body内容
    {
          
          
    	"settings": {
          
          
    		"analysis": {
          
          
    			"analyzer": {
          
           
    				"test_mapping_filter_analyzer": {
          
            
    					"tokenizer": "keyword",
    					"char_filter": ["my_mapping_filter"] 
    				}
    			},
    			"char_filter": {
          
            
    				"my_mapping_filter": {
          
           
    					"type": "mapping", 
    					"mappings": [
                            "CN => 中国",
                            "HUBEI => 湖北",
                            "WUHAN => 武汉"
                        ] 
    				}
    			}
    		}
    	}
    }
    

    Testar segmentação de palavras

    // GET http://localhost:9200/mapping-filter-test/_analyze
    // body内容
    {
          
          
        "text":"I come from WUHAN,HUBEI,CN",
        "analyzer": "test_mapping_filter_analyzer"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

    Como você pode ver, o conteúdo do texto inserido foi substituído pelo texto de acordo com o mapeamento que configuramos.

  • Usar arquivos de configuração

    Quando temos muitos mapeamentos, é inconveniente manter esse método de script. Portanto, o Elasticsearch suporta a leitura de arquivos no diretório especificado configurando o atributo mappings_path do filtro de caracteres de mapeamento para obter mapeamentos de mapeamento.

    No subdiretório config do diretório de instalação do Elasticsearch, crie uma pasta de análise, coloque o arquivo my_mapping.txt nela e mantenha o mapeamento correspondente no arquivo, conforme mostrado na figura abaixo.

    Insira a descrição da imagem aqui
    Insira a descrição da imagem aqui

    Nota: O arquivo txt deve ser codificado em UTF-8 e cada mapeamento precisa ser separado por novas linhas .

    Crie um índice para teste

    // PUT http://localhost:9200/mapping-filter-test2
    // body内容
    {
          
          
    	"settings": {
          
          
    		"analysis": {
          
          
    			"analyzer": {
          
           
    				"test_mapping_filter_analyzer": {
          
            
    					"tokenizer": "keyword",
    					"char_filter": ["my_mapping_filter"] 
    				}
    			},
    			"char_filter": {
          
            
    				"my_mapping_filter": {
          
           
    					"type": "mapping", 
    					"mappings_path": "analysis/my_mapping.txt"
    				}
    			}
    		}
    	}
    }
    

    Mappings_path precisa especificar o arquivo de configuração a ser lido. O caminho pode ser um caminho relativo ou um caminho absoluto baseado no diretório de configuração.

    // GET http://localhost:9200/mapping-filter-test2/_analyze
    // body内容
    {
          
          
        "text":"I come from WUHAN,HUBEI,CN",
        "analyzer": "test_mapping_filter_analyzer"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.2.4 filtro de caracteres pattern_replace

  • efeito

    O filtro de caracteres pattern_replace substitui qualquer caractere que corresponda a uma expressão regular pela substituição especificada.

  • Exemplo

    Aqui, usamos diretamente um analisador personalizado para demonstração, substituindo o número de telefone no conteúdo do texto pelo chinês “Este é um número de telefone”.

    // PUT http://localhost:9200/pattern-replace-filter-test
    // body内容
    {
          
          
    	"settings": {
          
          
    		"analysis": {
          
          
    			"analyzer": {
          
          
    				"test_pattern_replace_filter_analyzer": {
          
          
    					"tokenizer": "keyword",
    					"char_filter": ["my_pattern_replace_filter"]
    				}
    			},
    			"char_filter": {
          
          
    				"my_pattern_replace_filter": {
          
          
    					"type": "pattern_replace",
    					"pattern": "^(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\\d{8}$",
    					"replacement": "这是一段电话号码"
    				}
    			}
    		}
    	}
    }
    

    teste

    // GET http://localhost:9200/pattern-replace-filter-test/_analyze
    // body内容
    {
          
          
        "text":"13111111111",
        "analyzer": "test_pattern_replace_filter_analyzer"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.3 Tokenizador

5.3.1 Função

O segmentador de palavras é um meio de analisar e processar texto. A lógica básica de processamento é dividir o texto original em vários termos de granulação menor de acordo com as regras de segmentação de palavras pré-estabelecidas . O tamanho da granularidade depende das regras do segmentador de palavras .

Funciona após o filtro de caracteres (se houver).

O sistema possui alguns separadores de palavras integrados. Apresentaremos em detalhes vários separadores de palavras comumente usados. Para outros separadores de palavras, consulte a documentação oficial .

5.3.2 tokenizador padrão

  • efeito

    Este tokenizer dividirá o texto em vários termos de acordo com os limites das palavras definidos pelo algoritmo de segmentação de texto Unicode , e o tokenizer removerá a maioria dos sinais de pontuação.

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I like steak !",
        "tokenizer": "standard"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

    Como você pode ver, cada palavra é dividida em um termo e o ponto de exclamação é removido.

5.3.3 tokenizador de letras

  • efeito

    Este tokenizer irá segmentar o texto não alfabético, ou seja, quando houver texto não alfabético entre palavras adjacentes, ele será segmentado e o texto não alfabético também será removido.

    Nota: Ao encontrar caracteres chineses, eles serão processados ​​de acordo com as letras, ou seja, ao encontrar caracteres chineses, eles não serão separados.

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I,like&steak和西红柿!and#you",
        "tokenizer": "letter"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.3.4 tokenizador de espaço em branco

  • efeito

    Este tokenizer se divide quando espaços são encontrados.

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I like&steak!",
        "tokenizer": "whitespace"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.3.5 tokenizador de letras minúsculas

  • efeito

    Este tokenizer é semelhante ao tokenizer de letras. Ele dividirá o texto não alfabético e converterá cada termo segmentado em letras minúsculas. Esse filtro também descartará termos de texto não alfabéticos.

    É equivalente a uma combinação de tokenizador de letras e filtro de termos minúsculos, mas tem desempenho superior.

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I,like&steak和西红柿!and#you",
        "tokenizer": "lowercase"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.3.6 tokenizador clássico

  • efeito

    Este tokenizer segmenta texto com base em regras gramaticais e é muito útil para segmentar documentos em inglês . Funciona muito bem com siglas, nomes de empresas, endereços de e-mail e nomes de hosts da Internet.

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"My mail is [email protected]",
        "tokenizer": "classic"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.3.7 tokenizador de palavras-chave

  • efeito

    Este tokenizer é um tokenizer "noop" que pega qualquer texto fornecido e gera exatamente o mesmo texto como um único termo. Ele pode ser combinado com filtros de termos para normalizar a saída, como endereços de e-mail em letras minúsculas.

    Ou seja, trate o texto de entrada como um todo

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I like steak !",
        "tokenizer": "keyword"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.3.8 tokenizador de padrão

  • efeito

    Isso usa expressões regulares para dividir o texto em termos quando os separadores de palavras são correspondidos ou para capturar o texto correspondente como termos.

    O modo padrão é \W+, que divide o texto quando são encontrados caracteres que não sejam palavras.

  • Exemplo

    Divida o texto em termos ao combinar separadores de palavras

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"test,pattern,tokenizer!!!",
        "tokenizer": {
          
          
            "type":"pattern",
            "pattern":","
        }
    }
    

    De acordo com "," segmentação de palavras

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

    Capture texto correspondente como termos

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"\"test\"\"pattern,tokenizer!!!\"",
        "tokenizer": {
          
          
            "type":"pattern",
            "pattern":"\"((?:\\\\\"|[^\"]|\\\\\")+)\"",
            "group":1 
        }
    }
    

    Capture valores entre aspas duplas

    O grupo aqui se refere à API group() do objeto Matcher do Java.

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.4 Filtro de termos

5.4.1 Função

Os filtros de termos aceitam um fluxo de termos do tokenizer e podem modificar termos (por exemplo, letras minúsculas), remover termos (por exemplo, remover palavras irrelevantes) ou adicionar termos (por exemplo, sinônimos).

O sistema possui alguns filtros de termos integrados. Apresentaremos em detalhes vários filtros de termos comumente usados. Para outros filtros de termos, consulte a documentação oficial .

5.4.2 filtro de termo em minúsculas

  • efeito

    Este filtro de termos altera cada termo de letras maiúsculas para minúsculas, como Homem para homem, e oferece suporte à conversão de letras minúsculas para grego, irlandês e turco.

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I Like StEak !",
        "tokenizer": "keyword",
        "filter" : ["lowercase"]
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.4.3 filtro de termos maiúsculos

  • efeito

    Este filtro de termos mudará cada termo de minúsculas para maiúsculas, por exemplo, man para MAN.

    Perceber:

    Dependendo do idioma, um caractere maiúsculo pode ser mapeado para vários caracteres minúsculos. Usar o filtro de letras maiúsculas pode resultar na perda de informações de caracteres minúsculos, por isso é mais recomendado usar o filtro de termos em letras minúsculas

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I Like StEak !",
        "tokenizer": "keyword",
        "filter" : ["uppercase"]
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.4.4 filtro de comprimento e prazo

  • efeito

    Remove termos menores ou maiores que o comprimento de caracteres especificado. Por exemplo, você pode excluir termos com menos de 2 caracteres e termos com mais de 5 caracteres.

    Perceber:

    Este filtro remove termos inteiros que não atendem aos critérios. Se você quiser encurtar os termos para um comprimento específico, use o filtro de termo truncado .

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
    	"text": "I Like StEak !",
    	"tokenizer": "standard",
    	"filter": [{
          
          
    		"type": "length",
    		"min": 2,
    		"max": 4
    	}]
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.4.5 filtro de termo truncado

  • efeito

    Este filtro trunca os termos que excedem o limite de caracteres especificado. Esse limite é padronizado como 10, mas pode ser personalizado usando o parâmetro length.

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
    	"text": "I Like StEak !",
    	"tokenizer": "keyword",
    	"filter": [{
          
          
    		"type": "truncate",
    		"length": 5
    	}]
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.4.6 Filtro de termo dobrável ASCII

  • efeito

    Este filtro converte caracteres alfabéticos, numéricos e simbólicos (os primeiros 127 caracteres ASCII) que não estão no bloco Basic Latin Unicode em seus equivalentes ASCII (se presentes). Por exemplo, o filtro muda à para a.

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
    	"text": "açaí à la carte",
    	"tokenizer": "keyword",
    	"filter": ["asciifolding"]
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.4.7 filtro de termo de parada

  • efeito

    Este filtro remove palavras irrelevantes dos termos.

    Se não houver palavras irrelevantes personalizadas, o filtro excluirá as seguintes palavras irrelevantes em inglês por padrão:

    a, an, e, são, como, em, ser, mas, por, para, se, em, em, é, não, não, de, em, ou, tal, que, o, seu, então, lá, estes, eles, isto, para, foi, irá, com

    O filtro oferece suporte a listas de palavras irrelevantes predefinidas para vários idiomas além do inglês, e você também pode especificar suas próprias palavras irrelevantes como uma matriz ou arquivo.

    Por favor, verifique a documentação oficial para configuração detalhada

  • Exemplo

    Aqui estão apenas exemplos simples.

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
    	"text": "a quick fox jumps over the lazy dog",
    	"tokenizer": "standard",
    	"filter": ["stop"]
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.5 Analisadores integrados comuns

Elasticsearch fornece alguns analisadores integrados para os usuários usarem.

A seguir, apresentaremos alguns analisadores integrados comumente usados. Para analisadores integrados mais detalhados, consulte a documentação oficial.

5.5.1 analisador padrão

  • efeito

    Este analisador é o analisador padrão e é usado por padrão se nenhum analisador for especificado. Ele fornece uma função de segmentação de palavras baseada no algoritmo de segmentação de texto Unicode, que remove a maioria dos sinais de pontuação, converte termos em letras minúsculas e suporta a remoção de palavras irrelevantes. É adequado para a maioria dos idiomas, mas o suporte para chinês não é ideal: será dividido caractere por caractere e segmentado por palavra.

  • composição

    • filtro de caracteres

      nenhum

    • tokenizador

      tokenizador padrão

    • filtro de termo

      filtro de termo em minúsculas

      filtro de termo de parada (não habilitado por padrão)

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I Like StEak !",
        "analyzer": "standard"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.5.2 analisador simples

  • efeito

    O analisador divide o texto em termos com quaisquer caracteres não alfabéticos (como números, espaços, hifens e apóstrofos), descartando caracteres não alfabéticos e convertendo letras maiúsculas em minúsculas.

  • composição

    • filtro de caracteres

      nenhum

    • tokenizador

      tokenizador em minúsculas

    • filtro de termo

      nenhum

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I Like &StEak 和西红柿 2333 !",
        "analyzer": "simple"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.5.3 parar o analisador

  • efeito

    Este analisador é igual ao analisador simples, mas adiciona suporte para remoção de palavras irrelevantes.

  • composição

    • filtro de caracteres

      nenhum

    • tokenizador

      tokenizador em minúsculas

    • filtro de termo

      parar filtro de termo

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I Like &StEak the 和西红柿 2333 !",
        "analyzer": "stop"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.5.4 analisador de padrões

  • efeito

    Este analisador usa expressões regulares para dividir o texto em termos individuais e converter termos de letras maiúsculas para minúsculas. As expressões regulares devem corresponder aos delimitadores, não aos termos em si. As expressões regulares são padronizadas como \W+ (todos os caracteres que não são palavras).

    Nota: Expressões regulares Java são usadas aqui. Se o desempenho das expressões regulares for ruim, isso pode causar exceções de stackoverflow.

  • composição

    • filtro de caracteres

      nenhum

    • tokenizador

      tokenizador de padrão

    • filtro de termo

      filtro de termo em minúsculas

      filtro de termo de parada (não habilitado por padrão)

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I,Like&StEak,the,和西红柿,2333 !",
        "analyzer":"pattern"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.5.5 analisador de espaços em branco

  • efeito

    O analisador divide o texto em termos quando são encontrados caracteres de espaço em branco.

  • composição

    • filtro de caracteres

      nenhum

    • tokenizador

      tokenizador de espaço em branco

    • filtro de termo

      nenhum

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I Like &StEak the 和西红柿 2333 !",
        "analyzer":"whitespace"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.5.6 analisador de palavras-chave

  • efeito

    Este analisador é um analisador "noop" que retorna toda a string de entrada como um único termo.

  • composição

    • filtro de caracteres

      nenhum

    • tokenizador

      tokenizador de palavra-chave

    • filtro de termo

      nenhum

  • Exemplo

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"I Like &StEak the 和西红柿 2333 !",
        "analyzer":"keyword"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

5.6 Analisador Personalizado

Quando os analisadores integrados do Elasticsearch não conseguem atender às necessidades do negócio, podemos definir analisadores personalizados para atender às necessidades do negócio.

Os analisadores personalizados também são compostos por 0 ou mais filtros de caracteres + um tokenizer + 0 ou mais filtros de termos .

Os parâmetros de configuração comumente usados ​​do analisador são os seguintes :

nome do parâmetro significado
tipo Tipo de analisador. Aceita tipos de analisadores integrados. Para analisadores customizados, use custom ou omita esse parâmetro.
tokenizador Especifique o tokenizer a ser usado, que pode ser um tokenizer integrado ou um tokenizer personalizado.
filtro_char Especifica o filtro de caracteres a ser utilizado, que pode ser embutido ou customizado. O que é recebido aqui é um array.
filtro Especifica o termo filtro a ser utilizado, que pode ser embutido ou customizado. O que é recebido aqui é um array.

A seguir explicaremos cada configuração através de exemplos.

// PUT http://localhost:9200/custom-analyzer-test
// body内容
{
    
    
	"settings": {
    
    
		"analysis": {
    
    
			"analyzer": {
    
     // 当前索引中定义的分析器
				"my_analyzer": {
    
       // 自定义的分析器名称
                    "type":"custom", // 类型-自定义分析器
					"tokenizer": "my_tokenizer", // 自己定义的分词器
					"char_filter": ["&_to_and"],  // 自定义的分析器使用的字符过滤器集合
                    "filter":["my_stopwords","lowercase"] // 自定义的分析器使用的词项过滤器集合
				}
			},
			"char_filter": {
    
      // 当前索引中的字符过滤器集合
				"&_to_and": {
    
     // 自定义字符过滤器的名称
					"type": "mapping",  // 字符过滤器类型为mapping
                    "mappings":["& => and"]
				}
			},
            "tokenizer":{
    
     // 当前索引中定义的分词器
                "my_tokenizer":{
    
    
                    "type":"pattern",
                    "pattern":","
                }
            },
            "filter":{
    
      // 当前索引中定义的词项过滤器
                "my_stopwords":{
    
    
                    "type":"stop",
                    "stopwords": [ "the","a"]
                }
            }
		}
	}
}

Teste um analisador personalizado

// GET http://localhost:9200/custom-analyzer-test/_analyze
// body内容
{
    
    
    "text":"I,Like & StEak,the,和西红柿,2333 !",
    "analyzer":"my_analyzer"
}

O resultado é o seguinte:

Insira a descrição da imagem aqui

O diagrama de fluxo de trabalho deste analisador personalizado é mostrado na figura abaixo.

Insira a descrição da imagem aqui

5.7 analisador chinês

5.7.1 Suporte de análise do Elasticsearch para chinês

No analisador fornecido pelo Elasticsearch, o suporte ao chinês não é amigável o suficiente, não reconhece automaticamente frases em chinês, como: estudo, escola, etc.

Por exemplo, use o analisador padrão para analisar “Vou para a escola estudar”.

// GET http://localhost:9200/_analyze
// body内容
{
    
    
    "text":"我要去学校学习",
    "analyzer":"standard"
}

O resultado é o seguinte:

Insira a descrição da imagem aqui

Pode-se observar pelos resultados acima que o uso do analisador fornecido pelo Elasticsearch não pode atender às nossas necessidades de segmentação de palavras chinesas.

Portanto, costumamos usar o tokenizer IK para expansão.

5.7.2 Introdução ao segmentador de palavras IK

O segmentador de palavras IK é um segmentador de palavras Java gratuito e de código aberto. É um dos segmentadores de palavras chineses mais populares atualmente. É simples e estável, mas se você deseja resultados particularmente bons, precisa manter seu próprio dicionário de sinônimos e oferecer suporte personalizado dicionários.

5.7.3 Instalação do segmentador de palavras IK

  • Link para Download

    https://github.com/medcl/elasticsearch-análise-ik

    Observação: você deve escolher o segmentador de palavras ik correspondente à sua versão do Elasticsearch.

  • implantar

    Descompacte o segmentador de palavras IK baixado no subdiretório plugins do diretório de instalação do Elasticsearch.

Insira a descrição da imagem aqui

Após a descompactação, reinicie o Elasticsearch.

Nota: Se o erro for o seguinte ao iniciar:

java.lang.IllegalStateException: Could not load plugin descriptor for plugin directory [commons-codec-1.9.jar]
	at org.elasticsearch.plugins.PluginsService.readPluginBundle(PluginsService.java:403) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.findBundles(PluginsService.java:388) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.getPluginBundles(PluginsService.java:381) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:152) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.node.Node.<init>(Node.java:317) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.node.Node.<init>(Node.java:266) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:227) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:227) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:393) [elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170) [elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:161) [elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) [elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127) [elasticsearch-cli-7.8.0.jar:7.8.0]
	at org.elasticsearch.cli.Command.main(Command.java:90) [elasticsearch-cli-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:126) [elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) [elasticsearch-7.8.0.jar:7.8.0]
Caused by: java.nio.file.NoSuchFileException: D:\Software\Work\elasticsearch-7.8.0\plugins\commons-codec-1.9.jar\plugin-descriptor.properties
	at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79) ~[?:?]
	at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) ~[?:?]
	at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) ~[?:?]
	at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230) ~[?:?]
	at java.nio.file.Files.newByteChannel(Files.java:361) ~[?:1.8.0_91]
	at java.nio.file.Files.newByteChannel(Files.java:407) ~[?:1.8.0_91]
	at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384) ~[?:1.8.0_91]
	at java.nio.file.Files.newInputStream(Files.java:152) ~[?:1.8.0_91]
	at org.elasticsearch.plugins.PluginInfo.readFromProperties(PluginInfo.java:156) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.readPluginBundle(PluginsService.java:400) ~[elasticsearch-7.8.0.jar:7.8.0]
	... 15 more
[2023-04-18T17:23:45,388][ERROR][o.e.b.ElasticsearchUncaughtExceptionHandler] [LAPTOP-AN1JMLBC] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: java.lang.IllegalStateException: Could not load plugin descriptor for plugin directory [commons-codec-1.9.jar]
	at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:174) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:161) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:127) ~[elasticsearch-cli-7.8.0.jar:7.8.0]
	at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:126) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:92) ~[elasticsearch-7.8.0.jar:7.8.0]
Caused by: java.lang.IllegalStateException: Could not load plugin descriptor for plugin directory [commons-codec-1.9.jar]
	at org.elasticsearch.plugins.PluginsService.readPluginBundle(PluginsService.java:403) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.findBundles(PluginsService.java:388) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.getPluginBundles(PluginsService.java:381) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:152) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.node.Node.<init>(Node.java:317) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.node.Node.<init>(Node.java:266) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:227) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:227) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:393) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170) ~[elasticsearch-7.8.0.jar:7.8.0]
	... 6 more
Caused by: java.nio.file.NoSuchFileException: D:\Software\Work\elasticsearch-7.8.0\plugins\commons-codec-1.9.jar\plugin-descriptor.properties
	at sun.nio.fs.WindowsException.translateToIOException(WindowsException.java:79) ~[?:?]
	at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:97) ~[?:?]
	at sun.nio.fs.WindowsException.rethrowAsIOException(WindowsException.java:102) ~[?:?]
	at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(WindowsFileSystemProvider.java:230) ~[?:?]
	at java.nio.file.Files.newByteChannel(Files.java:361) ~[?:1.8.0_91]
	at java.nio.file.Files.newByteChannel(Files.java:407) ~[?:1.8.0_91]
	at java.nio.file.spi.FileSystemProvider.newInputStream(FileSystemProvider.java:384) ~[?:1.8.0_91]
	at java.nio.file.Files.newInputStream(Files.java:152) ~[?:1.8.0_91]
	at org.elasticsearch.plugins.PluginInfo.readFromProperties(PluginInfo.java:156) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.readPluginBundle(PluginsService.java:400) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.findBundles(PluginsService.java:388) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.getPluginBundles(PluginsService.java:381) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.plugins.PluginsService.<init>(PluginsService.java:152) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.node.Node.<init>(Node.java:317) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.node.Node.<init>(Node.java:266) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:227) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:227) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:393) ~[elasticsearch-7.8.0.jar:7.8.0]
	at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:170) ~[elasticsearch-7.8.0.jar:7.8.0]
	... 6 more

Você pode criar um subdiretório ik em plugins e então colocar os arquivos descompactados no subdiretório ik.

5.7.4 Explicação da configuração do segmentador de palavras IK

No diretório de configuração do segmentador de palavras ik, existem algumas configurações que vêm com o segmentador de palavras ik.

Insira a descrição da imagem aqui

O significado de cada configuração é mostrado na tabela a seguir

Nome do arquivo de configuração significado
principal.dic léxico principal
preposição.dic Partículas modais (também, e, mas, etc.)
stopword.dic Palavras de parada em inglês
quantificador.dic palavra de unidade de medida
sufixo.dic Palavras de sufixo (província, cidade, instituto, etc.)
sobrenome.dic Dicionário de Cem Sobrenomes de Família
extra_main.dic Vocabulário principal estendido
extra_single_word.dic、extra_single_word_full.dic、extra_single_word_low_freq.dic Biblioteca de palavras expandida
extra_stopword.dic Vocabulário de parada estendido
IKAnalyzer.cfg.xml Arquivo de configuração do tokenizador IK

5.7.5 Analisador integrado do tokenizador IK

Existem dois analisadores integrados ao segmentador de palavras IK: ik_max_word e ik_smart

  • i_max_word

    Divida o texto na granularidade mais fina

  • eu_inteligente

    Divida o texto na granularidade mais grosseira

  • Compare os dois analisadores com exemplos

    i_max_word

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"我要去学校学习",
        "analyzer":"ik_max_word"
    }
    

    O resultado é o seguinte:

    Insira a descrição da imagem aqui

    eu_inteligente

    // GET http://localhost:9200/_analyze
    // body内容
    {
          
          
        "text":"我要去学校学习",
        "analyzer":"ik_smart"
    }
    

    O resultado é o seguinte:

Insira a descrição da imagem aqui

5.7.6 Frase expandida com segmentador de palavras IK

Quando precisamos fazer com que certas palavras formem uma frase específica, podemos expandir a frase personalizada expandindo a frase.

Por exemplo, “League of Legends” não é uma frase específica em si, ela será dividida pelo tokenizer.

Vamos testar abaixo

// GET http://localhost:9200/_analyze
// body内容
{
    
    
    "text":"英雄联盟",
    "analyzer":"ik_smart"
}

O resultado é o seguinte:

Insira a descrição da imagem aqui

Como você pode ver, "League of Legends" será dividido em duas palavras: "Heroes" e "League". Não é isso que queremos. Queremos que "League of Legends" seja tratado como um único termo.

Neste momento, podemos configurá-lo no arquivo IKAnalyzer.cfg.xml no diretório de configuração do segmentador de palavras ik.

<?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"></entry>
	 <!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords"></entry>
</properties>

Fazemos a seguinte configuração

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

Crie o arquivo mydic.dic no diretório de configuração, escreva “League of Legends” no arquivo e reinicie o Elasticsearch.

Em seguida, testamos novamente

// GET http://localhost:9200/_analyze
// body内容
{
    
    
    "text":"英雄联盟",
    "analyzer":"ik_smart"
}

O resultado é o seguinte:

Insira a descrição da imagem aqui

Como você pode ver, “League of Legends” é tratado como um termo e não será dividido.

referência

[Silicon Valley] Tutorial do ElasticSearch desde o início até o domínio (com base nos novos recursos da pilha de tecnologia ELK elasticsearch 7.x + 8.x)

Acho que você gosta

Origin blog.csdn.net/weixin_42584100/article/details/131904890
Recomendado
Clasificación