【问题标题】:Elasticsearch Rails indexing issueElasticsearch Rails 索引问题
【发布时间】:2017-03-26 18:26:38
【问题描述】:

我正在使用 Elasticsearch 和 Elasticsearch Rails gem。我有两个通过 ActiveRecord 关联的模型,我正在尝试使用 Elasticsearch 对它们进行索引和搜索。

这是我的店铺模型

store.rb

has_many :addresses
has_many :jobs

def as_indexed_json
  self.as_json(include: {
    customer: { include: { addresses: {}, jobs: {} } },
    vendors: {}
  })
end

settings index: { number_of_shards: 1 } do
  mapping dynamic: 'false' do
    indexes :id
    indexes :store_number
    indexes :manager
    indexes :customer do
      indexes :first_name
      indexes :addresses do
        indexes :city
        indexes :state
      end
      indexes :jobs do
        indexes :job_number
      end
    end
  end
end

这是我的地址模型:

def as_indexed_json

end

settings index: { number_of_shards: 1 } do
  mapping dynamic: 'false' do
    indexes :city
    indexes :state
  end
end

我也使用 Searchkit 作为我的前端 UI。 Searchkit 能够聚合和显示商店模型中的所有属性(例如商店编号和经理)。但是,它无法查看嵌套项。换句话说,我无法聚合和检索客户下的工作下的 job_numbers。我可以查看客户姓名等。我尝试在作业和所有其他对象旁边使用 type: "nested" ,但这并没有什么不同。我也尝试过调整 as_indexed_json ,但没有任何运气。有人对此有任何想法吗?我被这个难住了。

【问题讨论】:

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


    【解决方案1】:

    尝试将您的 as_indexed_json 方法更改为:

    def as_indexed_json() {
      hash = self.as_json()
      hash['jobs'] = self.jobs.map(&:job_number)
      hash['address_state'] = self.addresses.map(&:state)
      hash['address_city'] = self.addresses.map(&:city)
      hash
    }
    

    像这样覆盖store 模型中的search

    def self.search(query)
      @search_definition = {
        query: {}
      }
      unless query.blank?
       @search_definition[:query] = {
         bool: {
           should: [
             {
               multi_match: {
                 query: query,
                 fields: ['store_number', 'manager', 'jobs', 'address_state', 'address_city'],
                 operator: 'and'
               }
             }
           ]
         }
       }
      else 
        @search_definition[:query] = { match_all: {} }
      end
       __elasticsearch__.search(@search_definition)
    end
    

    您还需要将映射设置更改为如下所示:

    settings index: { number_of_shards: 1 } do
      mapping do
       indexes :store_number, analyzer: 'keyword'
       indexes :jobs, analyzer: 'keyword'
       indexes :address_state, analyzer: 'keyword'
       indexes :address_city, analyzer: 'keyword'
       indexes :manager, type: 'multi_field' do 
              indexes :manager, analyzer: 'snowball'
              indexes :tokenized, analyzer: 'simple' 
       end
      end
    end
    

    这些索引设置只是示例。您可以使用最适合您用例的不同 typesanalyzerstokenizers

    有了这个,当你通过它的索引字段搜索一个商店时,你会得到结果,还有job_numbercitystate,虽然如果你想使用关联作为过滤器,搜索方法和映射会有所不同。

    【讨论】:

    • 感谢所有这一切,我想我听懂了你的意思。我认为我唯一不确定的是当您说要覆盖 as_indexed_json 方法时。地址和工作在客户模型上。那么,我应该把它放在客户模型中吗?我所拥有的层次结构是商店-> 客户-> 地址或商店-> 客户-> 工作。我了解 self.addresses.map(&:city),只是想确定我把它放在哪里。再次感谢您对此的帮助。
    • @MikeRiley 来自您发布的代码,store 模型 has_many addressesstore 还有 has_many jobs,我假设 store 是您的可搜索模型,即您要搜索store 记录。如果是这样,我发布的所有内容都会进入store 模型。
    猜你喜欢
    • 1970-01-01
    • 2012-11-10
    • 2018-10-12
    • 1970-01-01
    • 2014-03-06
    • 2021-02-21
    • 1970-01-01
    • 2015-04-20
    • 1970-01-01
    相关资源
    最近更新 更多