Hi. I am trying to get just the number of search results from the API.
I have the following query /search.json?q=query but i just need information about how many results there are. Not blurbs, cooked, etc.
Is it possible with discourse API?
I don’t think we return a “count” in the response, but it is something you can calculate yourself.
See the search API docs for a more detailed response example, but it will look something like this:
{
"posts": [],
"topics": [],
"users": [],
"categories": [],
"grouped_search_result": {}
}
Be default the API will return a max of 50 results. To calculate the count you need to just count the number of items in the posts array. The number items in the topics array should be the same so there is no reason to count that array too.
サイト内のすべてのトピックと投稿をダウンロードしようと、思いつく限りの方法を試しています。最新の投稿や人気投稿は件数が制限されており、現在はすべてのカテゴリを取得し、カテゴリごとに検索(サイト内でできる方法と同様)を試みています。例えば、当サイトでは「Q&A #q-a」と検索すると こちら で 50 件以上の結果が返ってきます。しかし、同じ文字列で discourse_api Ruby ガムを使って検索すると、5 件しか取得できません。
irb(main):123:0> topics["posts"].length
=> 5
irb(main):124:0> topics["topics"].length
=> 5
なぜ、インターフェースやご報告の内容と一致しないのでしょうか?データをエクスポートする最も簡単な方法はありますか?当サイトのコンテンツで NLP を行いたいのですが、データ取得自体が非常に難しい状況です。よろしくお願いいたします。
latest はページネーションされます。パラメータを適切に渡すだけで、API を通じてすべてのトピックにアクセスできるはずです。
検索もページネーションされます。
必要なパラメータをすべて理解するためのクイックガイドとして、Reverse engineer the Discourse API をお勧めします。
@sam さん、ありがとうございます!GET リクエストを見るだけでも、これはかなり直感的であることがわかります。2 ページ目を取得したい場合は、page という追加オプションを指定すればよいのです。また、discourse_api 関数で options を定義できることも確認できました。
# frozen_string_literal: true
module DiscourseApi
module API
module Search
# 指定された検索語に一致する検索結果を返します。
#
# @param term [String] 検索語
# @param options [Hash] カスタマイズ可能なオプションのセット
# @option options [String] :type_filter 指定されたタイプの結果を返します。
# @return [Array] 結果をハッシュの配列として返します。
def search(term, options = {})
raise ArgumentError.new("#{term} は必須ですが、指定されていません") unless term
raise ArgumentError.new("#{term} は必須ですが、指定されていません") unless !term.empty?
response = get('/search/query', options.merge(term: term))
response[:body]
end
end
end
end
そこで試してみたところ、1 ページ目と 2 ページ目で異なる結果が得られることを期待していました。あるいは、より明確に区別するために、1 ページ目と 3 ページ目で試してみましょう。クエリはすべての Q&A トピックを対象とします。
query = category["name"] + " #" + category["slug"]
=> "Q&A #q-a"
次に、discourse_api クライアントを使って 1 ページ目と 3 ページ目を取得します。
topics1 = client.search(query, options={"page": "1"})
topics3 = client.search(query, options={"page": "3"})
それぞれの最初のトピックを確認してみましょう。
=> {"id"=>220, "title"=>"Why am I exceeding the quota?", "fancy_title"=>"Why am I exceeding the quota?", "slug"=>"why-am-i-exceeding-the-quota", "posts_count"=>3, "reply_count"=>0, "highest_post_number"=>3, "image_url"=>nil, "created_at"=>"2018-06-01T12:56:12.120Z", "last_posted_at"=>"2018-06-15T16:41:44.736Z", "bumped"=>true, "bumped_at"=>"2018-06-15T16:41:44.736Z", "unseen"=>false, "pinned"=>false, "unpinned"=>nil, "visible"=>true, "closed"=>false, "archived"=>false, "bookmarked"=>nil, "liked"=>nil, "tags"=>["storage", "quota"], "category_id"=>26, "has_accepted_answer"=>false}
irb(main):148:0> topics3['topics'][0]
=> {"id"=>220, "title"=>"Why am I exceeding the quota?", "fancy_title"=>"Why am I exceeding the quota?", "slug"=>"why-am-i-exceeding-the-quota", "posts_count"=>3, "reply_count"=>0, "highest_post_number"=>3, "image_url"=>nil, "created_at"=>"2018-06-01T12:56:12.120Z", "last_posted_at"=>"2018-06-15T16:41:44.736Z", "bumped"=>true, "bumped_at"=>"2018-06-15T16:41:44.736Z", "unseen"=>false, "pinned"=>false, "unpinned"=>nil, "visible"=>true, "closed"=>false, "archived"=>false, "bookmarked"=>nil, "liked"=>nil, "tags"=>["storage", "quota"], "category_id"=>26, "has_accepted_answer"=>false}
これらは完全に同一です。つまり、page 変数が機能していないのではないかと思われます。Chrome の開発者ツールで確認すると、スクロールダウン(投稿がウィンドウ内で自動読み込みされるため)でトリガーされるポイントにおいて、page=2 が正しいパラメータであることが確認できます。
Request URL: https://ask.cyberinfrastructure.org/search?q=Q%26A%20%23q-a&page=2
Request Method: GET
Status Code: 200 (from ServiceWorker)
Referrer Policy: strict-origin-when-cross-origin
あるいは、パラメータリストを直接確認するのがより良いでしょう。
Query String Parameters
q: Q&A #q-a
page: 2
これはフォーム送信ではないため、例にあるような「Form Data」は表示されません。
何かご存知の方がいらっしゃいませんか?提案されたことは試してみましたが、次の論理的なステップが見当たりません。page 変数はリクエストと一緒に渡してもうまく動かないようです。
Discourse API gem は /search/query ルートを使用していますが、ページネーションには対応していないようです。一方、Discourse UI が使用する /search ルートはページネーションに対応しています。
ブラウザで http://forum.example.com/search.json?q=test にアクセスし、次に http://forum.example.com/search.json?q=test&page=2 を試すことで、これをテストできます。
Discourse API gem を使用せずに API 呼び出しを行う方法を見つける必要があるかもしれません。サイト内のすべてのトピックと投稿を取得することが目的であれば、/search ルートを使用するのは最適なアプローチではないようです。
代わりに http://forum.example.com/c/your-category-slug.json に対して API 呼び出しを行うことを試してみてください。リクエストでカテゴリのすべてのトピックが返されない場合、リクエストの topic_list には more_topics_url プロパティが含まれており、これが次のページへのルートを提供します。これは "/c/site-feedback?page=2" のような形式になります。JSON データを取得するには、URL に .json を追加する必要があります(例:/c/site-feedback.json?page=2)。
ありがとうございます!完全にうまくいきました。Python の requests を使うと、本当にずっと簡単です(Ruby に慣れるためにあえて難しくしていたのですが、必要な機能がないクライアントでした)。エクスポートはほとんど完了し、機械学習の部分はまだ手をつけていませんが、もし私が行った呼び出しに興味がある方がいれば、簡単なスクリプトはこちらにあります:https://github.com/hpsee/discourse-cluster。まもなく何か面白いクラスタリングを実装する予定です!
@sam さん、@simon さん、ありがとうございます!もし他の皆さんがトピックの単純なエクスポート、あるいはさらに進んで D3 を使った可視化によるクラスタリングに興味を持たれることがあれば、その手順をまとめた投稿を書きましたのでご覧ください:https://vsoch.github.io/2019/askci-discourse-cluster/。また、始めるために必要なものはすべて、以前リンクしたリポジトリにあります。