elasticsearch 添加以将令牌过滤器添加到SearchKick?

gxwragnw  于 2023-04-20  发布在  ElasticSearch
关注(0)|答案(1)|浏览(104)

我有一个相当简单的用例,但到目前为止,试图找到正确的语法是一件痛苦的事情。
我写了几个token过滤器:

searchkick **{
    settings: {
      analysis: {
        filter: {
          replace_mm: {
            type: 'pattern_replace',
            pattern: '(\\d)mm',
            replacement: '$1 mm ',
          },
          replace_x_1: {
            type: 'pattern_replace',
            pattern: '(\\d) ?(×|x)',
            replacement: '$1 x ',
          },
          replace_x_2: {
            type: 'pattern_replace',
            pattern: '(×|x) ?(\\d)',
            replacement: ' x $2',
          },
          searchkick_edge_ngram: {
            type: 'edge_ngram',
            min_gram: 1,
            max_gram: 50
          },
        },
        analyzer: {
          custom_index: {
            type: 'custom',
            tokenizer: 'standard',
            filter: [
              'replace_mm',
              'replace_x_1',
              'replace_x_2',
              'lowercase',
              'asciifolding',
              'searchkick_edge_ngram',
            ],
          },
          # https://github.com/ankane/searchkick/blob/ee62747af38b264574995341b70bdad432f65e0f/lib/searchkick/index_options.rb#L95
          searchkick_word_start_index: {
            type: 'custom',
            tokenizer: 'standard',
            filter: [
              'lowercase',
              'asciifolding',
              'searchkick_edge_ngram',
            ],
          },
        },
      },
    },
    mappings: {
      properties: {
        name: {
          type: 'text',
          analyzer: 'custom_index',
        },
        alternate_names: {
          type: 'text',
          analyzer: 'custom_index',
        },
        description: {
          type: 'text',
          analyzer: 'searchkick_word_start_index',
        },
      },
    },
    highlight: [
      :name,
    ],
    search_synonyms: [
      # ...
    ]
  }

我如何使索引+搜索利用这些过滤器。我希望一切都保持默认,我想只是覆盖过滤器,添加一些更多的,因为一切都完美的工作。

6ioyuze2

6ioyuze21#

这里的关键可能是利用merge_mappings参数并提供自定义Map/设置。

searchkick merge_mappings: true, mappings: {...}, settings: {...}

如果您想添加额外的令牌过滤器,您还需要创建额外的分析器才能使用它们,因为您不能直接使用令牌过滤器they are part of the analysis chain。因此,您开始的方式是正确的,将令牌过滤器添加到自定义设置中,但现在您还需要将新的分析器添加到自定义设置中,或覆盖现有的分析器。
工作的第二部分是提供自定义Map,以便利用新的分析器,除非您已经覆盖了字段的现有分析器。
看看默认设置是如何定义的,为了正确合并,您的设置结构需要如下所示:

{
  settings: {
    analysis: {
      filter: {
        replace_mm: {
          type: 'pattern_replace',
          pattern: '(\\d)mm',
          replacement: '$1 mm ',
        },
        replace_x_1: {
          type: 'pattern_replace',
          pattern: '(\\d) ?(×|x)',
          replacement: '$1 x ',
        },
        replace_x_2: {
          type: 'pattern_replace',
          pattern: '(×|x) ?(\\d)',
          replacement: ' x $2',
        },
      },
      analyzer: {
        my_new_analyzer: { ... },
        existing_analyzer: { ... },
      }
    },
  },
  mappings: {
    properties: {
      your_field: {
        type: text,
        analyzer: my_new_analyzer
      }
    }
  }

my_new_analyzer将是一个新的分析器,您可以将其用于自定义Map(如果提供)中的一个字段,而existing_analyzer将是考虑新令牌过滤器的现有分析器的覆盖。
覆盖哪个分析器取决于字段的类型,因为每个类型都有一个不同的分析器,名为searchkick_#{type}_index(完整列表可在此处获得)。
我希望这能让你走上正轨。

编辑

我也在尝试找出如何在搜索时使用这个

rows = Something.search({
      body: {
        query: {
          multi_match: {
            query: params[:query],
            type: '',
            fields: [
              '',
            ],
          },
        },
      },
    })

相关问题