Mas*_*ise 27 elasticsearch tire
我正在使用ElasticSearch with Tire来索引和搜索一些ActiveRecord模型,我一直在寻找索引和搜索关联的"正确"方法.我还没有找到对此最好的做法,所以我想问一下是否有人认为他们认为有效的做法.
作为一个示例设置(这是组成但说明了问题),让我们说我们有一本书,有章节.每本书都有一个标题和作者,以及一堆章节.每章都有文字.我们希望将书籍的字段和章节的文本编入索引,以便您可以按作者搜索书籍,也可以搜索包含特定词语的任何书籍.
class Book < ActiveRecord::Base
include Tire::Model::Search
include Tire::Model::Callbacks
has_many :chapters
mapping do
indexes :title, :analyzer => 'snowball', :boost => 100
indexes :author, :analyzer => 'snowball'
indexes :chapters, type: 'object', properties: {
chapter_text: { type: 'string', analyzer: 'snowball' }
}
end
end
class Chapter < ActiveRecord::Base
belongs_to :book
end
Run Code Online (Sandbox Code Playgroud)
那么我用以下搜索进行搜索:
s = Book.search do
query { string query_string }
end
Run Code Online (Sandbox Code Playgroud)
这不起作用,即使看起来索引应该这样做.如果相反我索引:
indexes :chapters, :as => 'chapters.map{|c| c.chapter_text}.join('|'), :analyzer => 'snowball'
Run Code Online (Sandbox Code Playgroud)
这使文本可搜索,但显然它不是一个很好的黑客,它失去了实际的相关对象.我尝试过各种搜索,例如:
s = Book.search do
query do
boolean do
should { string query_string }
should { string "chapters.chapter_text:#{query_string}" }
end
end
end
Run Code Online (Sandbox Code Playgroud)
也没有运气.如果有人有一个很好的,明确的使用Tire索引和搜索相关ActiveRecord对象的例子,那么这似乎是对知识库的一个非常好的补充.
感谢您的任何想法和贡献.
kar*_*rmi 51
对Tire中的ActiveRecord关联的支持正在发挥作用,但在您的应用程序中需要进行几次调整.毫无疑问,图书馆应该在这里做得更好,将来它肯定会做得更好.
也就是说,这是一个完整的Tire配置示例,可以与弹性搜索中的 Rails关联一起使用:active_record_associations.rb
让我在这里强调一些事情.
首先,您必须确保通知关联的父模型关于关联的更改.
鉴于我们有一个Chapter"属于"a 的模型Book,我们需要这样做:
class Chapter < ActiveRecord::Base
belongs_to :book, touch: true
end
Run Code Online (Sandbox Code Playgroud)
这样,当我们做类似的事情:
book.chapters.create text: "Lorem ipsum...."
Run Code Online (Sandbox Code Playgroud)
该book实例会收到有关添加章节的通知.
对此部分进行排序后,我们需要通知Tire有关更改,并相应地更新elasticsearch索引:
class Book < ActiveRecord::Base
has_many :chapters
after_touch() { tire.update_index }
end
Run Code Online (Sandbox Code Playgroud)
(毫无疑问,轮胎应该after_touch自己拦截通知,而不是强迫你这样做.另一方面,它证明了以一种不伤害你眼睛的方式绕着图书馆限制工作是多么容易.)
尽管README提到你必须在Rails <3.1中禁用自动"在JSON中添加根密钥",但很多人都忘了它,所以你必须将它包含在类定义中:
self.include_root_in_json = false
Run Code Online (Sandbox Code Playgroud)
现在是我们工作的重点 - 为我们的文档(模型)定义正确的映射:
mapping do
indexes :title, type: 'string', boost: 10, analyzer: 'snowball'
indexes :created_at, type: 'date'
indexes :chapters do
indexes :text, analyzer: 'snowball'
end
end
Run Code Online (Sandbox Code Playgroud)
请注意,我们title使用提升,created_at"日期"和相关模型的章节文本进行索引.所有数据都被有效地"去规范化"为弹性搜索中的单个文档(如果这样的术语有点意义).
作为最后一步,我们必须在elasticsearch索引中正确序列化文档.请注意我们如何利用ActiveRecord中的方便to_json方法:
def to_indexed_json
to_json( include: { chapters: { only: [:text] } } )
end
Run Code Online (Sandbox Code Playgroud)
完成所有这些设置后,我们可以在文档Book的Chapter部分和部分中搜索属性.
请运行开头链接的active_record_associations.rb Ruby文件以查看完整图片.
有关详细信息,请参阅以下资源:
请参阅StackOverflow答案:ElasticSearch&Tire:使用Mapping和to_indexed_json获取有关mapping/ to_indexed_jsoninterplay的更多信息.
请参阅此StackOverflow答案:索引ElasticSearch(Tire + ActiveRecord)中方法的结果,以了解在为具有关联的模型编制索引时如何对抗n + 1个查询.
| 归档时间: |
|
| 查看次数: |
9483 次 |
| 最近记录: |