Searchkick在指定字段时不搜索多个术语

时间:2015-09-23 15:26:56

标签: ruby-on-rails-4 elasticsearch searchkick

有人可以提供以下建议吗?

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

我的问题如下:

@products = Product.search query

允许上面列出的所有搜索字词,并在我添加

后立即返回预期结果
@products = Product.search query, fields: [:name, :manufacturer_name]

它只返回“myproduct”或“somecompany”的结果,而不是“myproduct somecompany”。

现在这不是什么大问题,因为我可以完全删除字段选项但是我需要将searchkicks word_start用于名称字段。所以我的最终查询是这样的:

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

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

我错过了一些非常明显的东西吗?我可以改变添加

operator: 'or'

但实际上我希望能够对名称进行搜索,添加其他条款,如果特定记录都存在,则会返回。

继承我的模型代码

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

由于

2 个答案:

答案 0 :(得分:4)

如果您的所有字段共享同一个分析器,则可以使用名为elasticsearch的{​​{1}}功能。如果不是这种情况,您可以使用cross_fields。很遗憾,query_string尚不支持searchkickcross_fields。所以,你必须自己做。

索引(不同的分析器)

query_string

使用cross_fields搜索

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'}
      }
    }
  }
}

使用query_string搜索

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

<强>更新 - 改变了我对这个solution之后使用不同分析器和多个字段的回答。

不幸的是,您自己将查询传递给@products = Product.search(body: { query: { query_string: { query: query, default_operator: "AND", fields: [ "name", "manufacturer_name", "grouped", ] } } } 会丢失elasticsearch功能,例如突出显示和转化,但是,您仍然可以将其添加到searchkick查询中。

在查询中添加高亮显示

elasticsearch

向查询添加转化

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

答案 1 :(得分:1)

最简单的方法是使用search_data方法将字段合并为一个字段。

class Product
  def search_data
    {
      full_name: "#{manufacturer_name} #{name}"
    }
  end
end

请务必在以后重新编制索引。然后使用全名进行搜索。 Searchkick的所有功能将继续起作用。