我已经查看了Tire文档,我知道可以使用Tire创建索引并将对象导入Elasticsearch,而无需使用ActiveModel包含。
我想让我的模型文件完全清除任何轮胎映射,而不是单独实现它们。
到目前为止,我已经为我的Member模型创建了一个索引对象:
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。
当我将红宝石哈希传递到import
方法时,id字段得到了尊重,这个问题就消失了,因为我现在可以执行以下操作来更新索引记录:
Tire.index('member') do
store(MemberIndexer.new(@member).attributes)
end
答案 0 :(得分:6)
update callback只不过是以下代码
after_save do
update_index
end
因此,如果您从某个地方调用@ member.update_index,它将更新该记录的索引。
答案 1 :(得分:1)
我不确定你不知道_id
是什么意思,你发布的代码就是@member.id
,对吧?
但你可以这样实现:
def update_es_index!
Tire.index 'members' do
store(@member)
end
end
它会调用store method来确定要发布到哪个网址。
答案 2 :(得分:0)
事实证明,在将Ruby哈希转换为JSON时,问题是某种误译。
当我将Ruby哈希传递给import
方法时,索引记录是使用适当的ActiveRecord id创建的,因此我只能使用包含ActiveRecord id的属性调用store
我想更新索引。