【问题标题】:Asciifolding with Elasticsearch and Tire in Rails 4 not Working在 Rails 4 中使用 Elasticsearch 和 Tire 进行 Asciifolding 不起作用
【发布时间】:2014-09-17 21:30:32
【问题描述】:

我在我的 rails 4 应用程序中创建了一个运行良好的搜索引擎,但我很难让 asciifolding 过滤器正常工作。我的模型有很多带有口音的术语,除非它们拼写完全正确,否则它们不会出现,即:我想要搜索“Rodriguez”以显示带有“Rodriguez”的结果。我尝试了许多不同的示例,但是由于某种原因,当我使用以下代码重置数据库时,搜索根本不起作用(我没有收到错误,但无论查询如何都没有出现)。

这是我的模型:

class Product < ActiveRecord::Base
    include Tire::Model::Search
    include Tire::Model::Callbacks

    settings :analysis => {
        :analyzer => {
          :default => {
            :tokenizer  => "standard",
            :filter  => ["standard", "asciifolding"]
          }
        }
    } do

        mapping do
          indexes :id, type: 'integer', index: :not_analyzed
          indexes :name, boost: 5, analyzer: 'default'
          indexes :website, index: :not_analyzed
          indexes :price, type: 'integer', index: :not_analyzed
          indexes :artist, boost: 3, analyzer: 'default'
          indexes :company, boost: 4, analyzer: 'default'
          indexes :date, type: 'date', index: :not_analyzed
        end
    end

    def self.search(params)
      tire.search(page: params[:page], per_page: 12) do
        query { string params[:query], default_operator: "AND" } if params[:query].present?
      end
    end

在测试之前,我使用以下命令清除数据库:

rake db:setup

然后我运行:

rake environment tire:import CLASS=Product FORCE=true

我查看了许多不同的资源,包括 elasticsearch 和轮胎文档,但无论出于何种原因(我预计会犯一个愚蠢的错误),它根本不起作用。小提示,为了填充我的数据库,我一直在导入一个 csv 文件,但我不明白为什么这会产生任何影响,特别是考虑到在这种形式的搜索中没有出现任何内容(当我删除时它工作正常,没有重音问题设置部分,只有映射块和搜索方法)。我需要调用某种 Tire.index 并导入吗?任何帮助表示赞赏!

更新

所以我对搜索查询进行了编辑,修复了问题,但又提出了一个新问题:

    def self.search(params)
          tire.search(page: params[:page], per_page: 12) do
            query { string params[:query], analyzer: :search_analyzer, :default_field => 'name' } if params[:query].present?
          end
        end

通过识别默认字段,我现在可以搜索不可知的重音,但现在我的搜索仅限于名称,并且我无法接收以前工作的其他索引属性的结果。有谁知道如何设置多个默认字段?

【问题讨论】:

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


    【解决方案1】:

    这是我在生产中使用的示例。它不是解决您的问题的方法,但它会让您起步。我的代码将ICU plugin 用于icu_foldingshingle_filtermulti_fieldTire。另请注意,Tire 自 2013 年 9 月起为 retired,如果是新项目,您应该使用 elasticsearch-rubyelasticsearch-rails。使用此代码,我可以自动完成 Rod 查找 Rodríguez 之类的情况。

    class Profile
      # ...
      include Tire::Model::Persistence
      # I'm also using ES as persistance storage.
      include Tire::Model::DynamicPersistence
    
      property :title, analyzer: 'snowball', type: :multi_field,
        fields: {
          title: {
            type: 'string',
            boost: 20.0,
            search_analyzer: "autocomplete_search_analyzer",
            index_analyzer: "autocomplete_indexer_analyzer"
          },
          completed: {
            type: 'string',
            boost: 15.0,
            search_analyzer: "autocomplete_search_analyzer",
            index_analyzer: "autocomplete_indexer_analyzer"
        }
      }
    
      CONFIGURATION = {
        settings: {
          analysis: {
            analyzer: {
              shingle_analyzer: {
                tokenizer: "keyword",
                filter: ["icu_folding", "lowercase", "shingle_filter"]
              },
              sx_index_analyzer: {
                tokenizer: "standard",
                filter: ["icu_folding", "lowercase"]
              },
              sx_search_analyzer: {
                tokenizer: "standard",
                filter: ["icu_folding", "lowercase"]
              }
            },
            filter: {
              shingle_filter: {
                type: "shingle",
                min_shingle_size: 2,
                max_shingle_size: 5
              }
            }
    
          }
        },
    
        mappings: {
          profile: {
            "_all" => {
              enabled: true,
              index_analyzer: "sx_index_analyzer",
              search_analyzer: "sx_search_analyzer"
            },
    
           properties: {
            title: {
             type: "multi_field",
             fields: {
              title: {
                type: "string",
                store: "yes",
                boost: 20.0
                #index_analyzer: "sx_index_analyzer",
                #search_analyzer: "sx_search_analyzer"
              },
              sortable: {
                type: "string",
                index: "analyzed"
              },
              autocomplete: {
                type: "string",
                index_analyzer: "shingle_analyzer",
                boost: 15.0
              },
             }
            }
           }
          }
        }
      }
    
      def self.rebuild_index
        Tire.index Profile.index_name do
          delete if Profile.index.exists?
          create Profile::CONFIGURATION
        end
      end
    end
    

    希望对你有帮助!

    【讨论】:

    • 谢谢你,我现在没有时间测试这个,但我会告诉你它是如何工作的!
    • 如果您认为这是正确的答案,请务必将其标记为适当的。谢谢。 ;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 2013-08-28
    • 2012-07-25
    • 1970-01-01
    • 2014-06-20
    • 1970-01-01
    相关资源
    最近更新 更多