8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

QiitaAPIを通じて複数のタグを持つ記事を検索する

Last updated at Posted at 2014-10-13

Ruby初心者なのでなにかお気づきの点がありましたらご教授いただけると幸いです。

QiitaApiAccessor

QiitaAPIとの通信, 受信情報のハッシュ化を担当している。
@result_jsonをローカル変数にしたいのだけど, openブロック内のローカル変数になってしまうので出来ない...
get_with_tag内のローカル変数にならできるけど結局result_json = {}としてopen内で更新みたいな書き方になってしまって綺麗じゃない...

require 'open-uri'
require 'json'

class QiitaApiAccessor

  def initialize
    @qiita_url = 'http://qiita.com/api/v2'
    @result_json = {}
  end

  def get_with_tag(tag_name)
    open("#{@qiita_url}/tags/#{tag_name}/items?page=1&per_page=100") do |uri|
      @result_json = JSON.parse(uri.read, symbolize_names: true)
    end
    @result_json
  end

end

QiitaArticle

一つの記事についての情報を保持する。
has_tag?メソッドでは, 大文字小文字にかかわらず判定が出来るようupcaseを使用している。

class QiitaArticle
  
  def initialize (article_hash)
    @data = article_hash
    @title = article_hash[:title]
    @url = "http://qiita.com/api/v2/items/#{article_hash[:id]}"
    @tags = article_hash[:tags].map { |tag| tag[:name] }
    @body = article_hash[:body]
  end

  attr_reader :title, :url, :tags, :body

  def has_tag?(tag_name)
    tags = @data[:tags]
    tags.any?{ |tag_info| tag_info[:name].upcase == tag_name.upcase }
  end

end

MultiTagsSearcher

これがメインのクラス。コンストラクタにQiitaApiAccessor#get_with_tagの戻り値と検索したいタグのリストを渡してやる。
group_by_relevanceによって含んでいる対象タグの数によってグループ化する。

class MultiTagsSearcher

  def initialize(articles_data, tags)
    @articles = articles_data.map { |data| QiitaArticle.new(data) }
    @tags = tags
  end

  attr_reader :articles

  def group_by_relevance
    @articles.group_by do |article|
      @tags.count { |tag| article.has_tag?(tag) }
    end
  end

end

使い方

QiitaApiAccessor#get_with_tagにメインとなるキーワードタグを渡す。
その戻り値と、キーワードタグを含む検索したいタグ名のリストを、MultiTagsSearcherに渡してgroup_by_relevanceしてやる。
すると含んでいる対象タグ数 => [QiitaArticleのインスタンス]というハッシュが得られるので、適当にQiitaArticle#urlとかで記事のurlを取ってこられます。

問題点・改善点

QiitaAPIの都合上一度に100件までしか記事の情報を取得できないので, 本当はループで全件取得してからMultiTagsSearcherに渡したい。
が、そうすると5000件とか普通に行く場合もあるからQiitaArticleのインスタンスが無駄に大量生成されてしまうし、時間もかかる。
なので、検索の際のキーワードタグには記事数の少なそうなものを選ぶことでお茶を濁す...
rubyではなくsinatraをキーワードにするだけで結果がかなり違ってくる。
けどそれじゃ根本的な解決になってない。なにか良い方法ありましたら教えて下さい。

8
7
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?