dev*_*lip 5 ruby sql sqlite ruby-on-rails ruby-on-rails-3
我有如下要求
诗属于诗人
诗人有很多诗
如果用户搜索"ruby"这个词
它应该给,
所有诗歌中使用单词ruby的总次数.
显示所有带有红宝石一词的诗歌.
每首诗中使用单词ruby的次数.
使用单词ruby的诗人总数.
每位诗人使用红宝石这个词的总次数.
所以我在模型诗中的查询就在这里
poems= where("poem_column like ?", "%#{word}%" )
@results = {}
poems.each do |poem|
words = poem.poem_column.split
count = 0
words.each do |word|
count += 1 if word.upcase.include?(word.upcase)
end
@results[poem] = count # to get each poem using word ruby
end
Run Code Online (Sandbox Code Playgroud)
并让诗人在诗歌模型中占有一席之地
@poets = poems.select("distinct(poet_id)")
@poets.each do |poet|
@poets_word_count << poems.where("poet_id = #{poem.poet_id}").count
end
Run Code Online (Sandbox Code Playgroud)
诗歌大约50k.它花了不到1分钟.我知道我的做法是错误的,但我不能以任何其他方式对其进行优化.
我认为以下几行花费了太多时间,因为它循环了所有诗歌的每个单词.
words.each do |word|
count += 1 if word.upcase.include?(word.upcase)
end
Run Code Online (Sandbox Code Playgroud)
你们中的任何人都可以告诉我优化它的方法.由于缺乏查询知识,我无法以任何其他方式做到这一点.
提前致谢
不是答案,只是测试。
首先,在保存每首诗时减少提取关键字的数据:
rails g resource Keyword word occurrences poem_id:integer
rails db:migrate
Run Code Online (Sandbox Code Playgroud)
然后在你的 Poem 模型中:
# add more words
EXCLUDED_WORDS = %w( the a an so that this these those )
has_many :keywords
before_save :set_keywords
# { :some => 3, :word => 2, :another => 1}
def keywords_hash(how_many = 5)
words = Hash.new 0
poem_column.split.each do |word|
words[word] += 1 if not word.in? EXCLUDED_WORDS
end
Hash[words.sort { |w, w1| w1 <=> w }.take(how_many)]
end
def set_keywords
keywords_hash.each do | word, occurrences |
keywords.create :word => word, :occurrences => occurrences
end
end
Run Code Online (Sandbox Code Playgroud)
在Keyword模型中:
belongs_to :poem
def self.poem_ids
includes(:poem).map(&:poem_id)
end
def self.poems
Poem.where(id: poem_ids)
end
Run Code Online (Sandbox Code Playgroud)
然后当您有要搜索的词时:
keywords = Keyword.where(word: word)
poems = keywords.poems
poets = poems.poets
Run Code Online (Sandbox Code Playgroud)
要使用最后一部分,您需要在Poem模型中:
def self.poet_ids
includes(:poet).map(&:poet_id)
end
def self.poets
Poet.where(id: poet_ids)
end
Run Code Online (Sandbox Code Playgroud)
据我所知,这种方式只需要 3 个查询,不需要连接,所以这似乎是有道理的。
我会思考如何扩展这种方式来搜索整个内容。
| 归档时间: |
|
| 查看次数: |
256 次 |
| 最近记录: |