【问题标题】:Update Tire index without using Tire::Model::Callbacks不使用 Tire::Model::Callbacks 更新轮胎索引
【发布时间】:2013-04-10 19:42:08
【问题描述】:

我已经阅读了 Tire 文档,并且了解可以使用 Tire 创建索引并将对象导入 Elasticsearch,而无需使用 ActiveModel 包含。

我想让我的模型文件完全没有任何轮胎映射,而是单独实现它们。

到目前为止,我已经为我的成员模型创建了一个索引对象,如下所示:

class MemberIndexer
  def initialize(member)
    @member = member
  end

  def attributes
    {
      id: @member.id,
      name: @member.full_name,
      age: @member.age,
      birthday: @member.birthday,
      type: 'member'
    }.to_json
  end

  def self.refresh_index
    Tire.index 'members' do
      delete
      create mappings: {
        member: {
          properties: {
            id: { type: 'integer' },
            name: { type: 'string', boost: 5 },
            age: { type: 'integer' },
            birthday: { type: 'date' }
          }
        }
      }

      Member.find_in_batches do |members|
        import members.map { |m| MemberIndexer.new(m).attributes }
      end
    end
  end
end

这工作正常,索引已创建,我可以正确搜索。我缺少的是可以使用Tire::Model::Callbacks 包含的回调。是否可以使用轮胎更新索引中的单个记录而无需在模型本身中包含Tire::Model::Callbacks

例如,如果我更新Member,我希望能够手动更新成员索引中的相应项目。在不知道该项目的_id 的情况下这可能吗?

我应该只使用 ActiveRecord id 搜索对象,然后在索引上使用 update 方法吗?

更新: 我对 ES 不是使用实际 ActiveRecord id 而是通过在 ES 中生成唯一 id 来索引成员这一事实感到困惑,即使我认为我在属性 json 中传递了一个 id。

当我将 ruby​​ 哈希传递给 import 方法时,id 字段得到了尊重,这个问题就消失了,因为我现在可以执行以下操作来更新索引记录:

Tire.index('member') do
  store(MemberIndexer.new(@member).attributes)
end

【问题讨论】:

    标签: ruby-on-rails elasticsearch tire


    【解决方案1】:

    update callback无非就是下面的代码

    after_save do
      update_index
    end
    

    因此,如果您从某个地方调用@member.update_index,它将更新该记录的索引。

    【讨论】:

    • 鉴于我的 Member 类中没有包含轮胎模块,所以 @member 上没有 update_index 方法。最后虽然问题是提交 json 到 import 方法。
    • 或者,甚至更好 - 仅在我们的索引字段更改时更新: updated_index if changed & %w(name email deleted real_name)
    【解决方案2】:

    我不确定你不知道_id 是什么意思,从你发布的代码来看,它是@member.id,对吧?

    但是你可以像这样实现它:

    def update_es_index!
      Tire.index 'members' do
        store(@member)
      end
    end
    

    它将调用store method,它将确定要发布到哪个 URL。

    【讨论】:

    • 由于某种原因,当我将属性转换为 json 时,批量 import 方法不尊重 Member 对象的 id,而是在 ES 中生成一个唯一的 id。一旦我向 import 方法提交了一个 ruby​​ 哈希,一切都按预期工作。
    【解决方案3】:

    原来问题是在将 Ruby 哈希转换为 JSON 时出现了某种错误翻译。

    当我将 Ruby 哈希传递给 import 方法时,索引记录是使用适当的 ActiveRecord id 创建的,因此当我想更新时,我可以使用包含 ActiveRecord id 的属性调用 store索引。

    【讨论】:

      猜你喜欢
      • 2012-04-30
      • 1970-01-01
      • 2012-03-22
      • 1970-01-01
      • 2012-04-14
      • 1970-01-01
      • 2013-02-28
      • 2012-06-30
      • 1970-01-01
      相关资源
      最近更新 更多