本文介绍了指定字段时,Searchkick 不搜索多个词的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人可以就以下问题提供建议吗?

Can anyone provide advice on the following please?

我正在使用 searchkick/elasticsearch 并想在多个字段(名称、制造商)中搜索一个或多个关键术语.因此,例如,如果我正在寻找名为myproduct"的产品使我的somemanufacturer"我希望看到这个结果出现在我搜索myproduct"、somemanufacturer"或myproduct somemanufacturer"中,因为这两个术语都包括在内在名称或制造商字段中.

I'm using searchkick / elasticsearch and would like to search for a key term or terms across multiple fields (name, manufacturer). So for example if im looking for a product called "myproduct" made my "somemanufacturer" i'd expect to see this result appear if I search either "myproduct", "somemanufacturer" or "myproduct somemanufacturer" as both these terms are included either in name or manufacturer fields.

我的问题如下:

@products = Product.search query

允许上面列出的所有搜索词并在我添加后立即返回预期结果

Allows all the search terms listed above and returns expected result however as soon as I add

@products = Product.search query, fields: [:name, :manufacturer_name]

它只会返回myproduct"或somecompany"的结果,而不是myproduct somecompany".

It will only return a result for "myproduct", or "somecompany", but not "myproduct somecompany".

现在这没什么大不了的,因为我可以完全删除字段选项,但我需要对名称字段使用 searchkicks word_start.所以我的最终查询是这样的:

Now this isn't a big deal as I can remove the fields option entirely BUT I need to utilise searchkicks word_start for the name field. So my final query is something like this:

@products = Product.search query, fields: [{name: :word_start}, :manufacturer_name]

我希望用户搜索产品的第一个字符串,并且也能够输入制造商,例如myprod somecompany"不幸的是,当我希望它返回名为 myproduct 的产品时,返回零结果,由 somecompany 制造.

I'd like users to search for the 1st string of the product and be able to enter a manufacturer too eg "myprod somecompany" unfortunately this returns zero results when I was hoping it would return the product named myproduct, made by somecompany.

我在这里遗漏了一些非常明显的东西吗?我可以更改添加

Am i missing something really obvious here? I can change add

operator: 'or'

但我真的希望能够对名称进行部分搜索,添加其他术语,如果两个都存在于特定记录中,则返回.

but really i want to be able to part search on the name, add additional terms and if both are present for a particular record it gets returned.

这里还有我的模型代码

class Product < ActiveRecord::Base
 searchkick word_start: [:name]
end

谢谢

推荐答案

如果您的所有字段共享同一个分析器,您可以使用名为 cross_fieldselasticsearch 功能.如果不是这种情况,您可以使用 query_string.不幸的是,searchkick 还不支持 cross_fieldsquery_string.所以,你必须自己做.

If all of your fields share the same analyzer, you can use elasticsearch feature called cross_fields. If it is not the case, you can use query_string. Unfortunately searchkick does not support cross_fields and query_string yet. So, you have to do it by yourself.

索引(不同的分析器)

searchkick merge_mappings: true, mappings: {
  product: {
    properties: {
      name: {
        type: 'string',
        analyzer: 'searchkick_word_start_index',
        copy_to: 'grouped'
      },
      manufacturer_name: {
        type: 'string',
        analyzer: 'default_index',
        copy_to: 'grouped'
      },
      grouped: {
        raw: {type: 'string', index: 'not_analyzed'}
      }
    }
  }
}

使用 cross_fields 搜索

@products = Product.search(body: {
  query: {
     multi_match: {
                  query: query,
                  type: "cross_fields",
                  operator: "and",
                  fields: [
                      "name",
                      "manufacturer_name",
                      "grouped",
                  ]
              }
         }
}

使用 query_string 搜索

@products = Product.search(body: {
  query: {
      query_string: {
                  query: query,
                  default_operator: "AND",
                  fields: [
                      "name",
                      "manufacturer_name",
                      "grouped",
                  ]
              }
         }
}

更新- 按照此解决方案更改了我对使用不同分析器和多字段的回答.

Update- Changed my answer to the use of different analyzers and multi fields following the this solution.

不幸的是,自己将查询传递给 elasticsearch 会丢失 searchkick 功能,例如突出显示和转换,但是,您仍然可以做到,将其添加到 elasticsearch 查询.

Unfortunately passing the query to elasticsearch by yourself you lose searchkick features like highlight and conversions, but, you can still do it, adding it to the elasticsearch query.

向查询添加突出显示

@products = Product.search(body: {
  query: {
    ...
  }, highlight: {
    fields: {
      name: {},
      manufacturer_name: {}
    }
  }

向查询添加转化

@products = Product.search(body: {
  query: {
    bool: {
      must: {
        dis_max: {
          queries: {
            query_string: {
              ...
            }
          }
        }
      },
      should: {
        nested: {
          path: 'conversions',
          score_mode: 'sum',
          query: {
            function_score: {
              boost_mode: 'replace',
              query: {
                match: {
                  "conversions.query": query
                }
              },
              field_value_factor: {
                field: 'conversions.count'
              }
            }
          }
        }
      }
    }
  }

这篇关于指定字段时,Searchkick 不搜索多个词的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 16:56