4

I'm using Tire for Elastic Search. In my application I have 2 models; Price and Product.

I'm trying to search my Price class and use the Product it belongs to's :name attribute for the search field. Right now if I had a product called Product 1 and type in "pro", "prod" or "duct", no results come up. But typing "product" or "Product" shows the results. I believe the problem lies in my mapping. I looked at the query and its:

...localhost:3000/search/results?utf8=%E2%9C%93&query=product

When I think it should be:

...localhost:3000/search/results?utf8=%E2%9C%93&query:product=product

Judging by this question: ElasticSearch mapping doesn't work

I don't know how to make my params[:query] to take the product.name only though. I tried to use: string params[:query], default_field: "product.name" but that didn't work.

I don't want to use the _all field.

Here is my code:

Price.rb

  include Tire::Model::Search
  include Tire::Model::Callbacks

  def self.search(params)
    tire.search(load: true, page: params[:page], per_page: 20) do
       query do
         boolean do
            must { string params[:query] } if params[:query].present?
            must { term :private, false }
         end
       end
       sort do
         by :date, "desc"
         by :amount, "asc"
       end
    end
  end

  def to_indexed_json
    to_json( include: { product: { only: [:name] } } )
  end

  mapping do
    indexes :id,        type: "integer"
    indexes :amount,    type: "string", index: "not_analyzed"
    indexes :date,      type: "date",   index: "not_analyzed"
    indexes :private,   type: "boolean"
    indexes :product do
      indexes :name, type: "string", analyzer: "custom_analyzer"
    end
  end

  settings analysis: {
    analyzer: {
      custom_analyzer: {
        tokenizer: [ "whitespace", "lowercase" ],
        filter: [ "ngram_filter", "word_delimiter_filter" ],
        type: "custom"
      }
    },
    filter: {
      ngram_filter: {
        type: "nGram",
        min_gram: 2,
        max_gram: 15
      }
    },
    filter: {
      word_delimiter_filter: {
        type: "word_delimiter",
        generate_word_parts: true,
        generate_number_parts: true,
        preserve_original: true,
        stem_english_possessive: true
      }
    }
  }

So does anyone have any suggestions or know how to set the query field to use the Product name only?

Thank you.

4

2 回答 2

5

当你这样做

 query   { string params[:query] } 

并且查询未指定字段,您正在搜索魔术_all字段。此字段有自己的分析器设置 - 它不会使用您为名称字段设置的设置。

您可以配置该_all字段以使用您的分析器,更改默认分析器或更改您的查询以name专门查询该字段,例如

 query { string params[:query], :default_field => 'name'}
于 2012-08-24T21:13:42.830 回答
0

这让我非常头疼,所以我最终去了Ransack,它非常容易理解和使用。

于 2012-08-30T02:22:28.440 回答