ElasticSearch“H& R Block”具有部分单词搜索功能

时间:2015-03-12 13:15:46

标签: elasticsearch

要求是能够搜索以下术语:

  1. " H& R"找到" H& R Block"。
  2. 我已设法使用word_delimiter单独实现此要求,如本回答elasticsearch tokenize "H&R Blocks" as "H", "R", "H&R", "Blocks"

    所述

    使用ruby代码:

    {
      char_filter: {
        strip_punctuation: { type: "mapping", mappings: [".=>", ",=>", "!=>", "?=>"] },
      },
      filter: {
        my_splitter: { 
          type: "word_delimiter", 
          preserve_original: true 
        }
      },
      analyzer: {
        my_analyzer {
          char_filter: %w[strip_punctuation],
          type: "custom",
          tokenizer: "whitespace",
          filter: %w[lowercase asciifolding my_splitter]
        }
      }
    }
    

    但是,在同一个查询中,我们需要自动完成功能或部分字匹配,所以

    1. " Ser"," Serv"," Servi"," Servic"和"服务"所有发现"服务"和"服务"。
    2. 我已经设法使用ngram单独实现此要求。

      {
        char_filter: {
          strip_punctuation: { type: "mapping", mappings: [".=>", ",=>", "!=>", "?=>"] }
        },
        analyzer: {
          my_analyzer: {
            char_filter: %w[strip_punctuation],
            tokenizer: "my_ngram",
            filter: %w[lowercase asciifolding]
          }
        },
        tokenizer: {
          my_ngram: {
            type: "nGram",
            min_gram: "3",
            max_gram: "10",
            token_chars: %w[letter digit]
          }
        } 
      }
      

      我无法一起实现它们。当我使用ngram时,短词会被忽略,因此" H& R"被遗漏了。当我使用word_delimiter时,部分单词搜索停止工作。下面,我最近尝试合并两个要求,它导致支持部分单词搜索但不支持" H& R"

      {
        char_filter: {
          strip_punctuation: { type: "mapping", mappings: [".=>", ",=>", "!=>", "?=>"] }
        },
        filter: {
          my_splitter: {
            type: "word_delimiter",
            preserve_original: true
          }
        },
        analyzer: {
          my_analyzer: {
            char_filter: %w[strip_punctuation],
            type: "custom",
            tokenizer: "my_tokenizer",
            filter: %w[lowercase asciifolding my_splitter]
          }
        },
        tokenizer: {
          my_tokenizer: {
            type: "nGram",
            min_gram: "3",
            max_gram: "10",
            token_chars: %w[letter digit]
          }
        } 
      }
      

1 个答案:

答案 0 :(得分:1)

您可以使用映射中的multi_field以多种方式为同一字段编制索引。您可以在默认字段中使用自定义标记生成器的全文搜索,并为自动完成需求创建特殊索引。

"title": {
    "type": "string",
    "fields": {
        "raw":   { "type": "string", "index": "not_analyzed" }
    }
}

执行自动填充时,您的查询需要略有不同,因为该字段将为title.raw,而不仅仅是title

一旦字段以对查询有意义的所有方式编制索引,您就可以使用布尔值来查询索引" should"查询,匹配标记化版本和单词开始查询。对于匹配完整单词的第一个查询,可能需要提供更大的提升才能获得直接命中率。