Discourses API get just the number of search results

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),但仅仅获取数据就已经非常困难了。谢谢!

“最新”支持分页,你只需正确传递参数,就能通过 API 访问所有主题。

搜索功能也支持分页。

我推荐这个链接作为快速入门,帮助你了解所需的所有参数:https://meta.discourse.org/t/how-to-reverse-engineer-the-discourse-api/20576。

谢谢 @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。如果该请求未返回类别中的所有主题,则响应的 topic_list 中将包含一个 more_topics_url 属性,该属性会提供下一页主题的链接,例如 "/c/site-feedback?page=2"。你需要在 URL 后添加 .json 以获取 JSON 数据(例如 /c/site-feedback.json?page=2)。

谢谢!这完全奏效了,而且用 Python 的 requests 库做起来轻松了(我故意把 Ruby 搞复杂些,以便更熟悉它,但那个客户端缺少我需要的功能)。导出工作基本完成了,我还没开始做机器学习相关的事,不过如果有人对我调用的 API 感兴趣,我的快速脚本在这里:https://github.com/hpsee/discourse-cluster。希望很快能做一些很酷的聚类分析!

再次感谢 @sam@simon!如果其他人将来有兴趣进行主题的简单导出,或者更进一步,使用 d3 进行聚类与可视化,我写了一篇简短的帖子,详细介绍了具体步骤:https://vsoch.github.io/2019/askci-discourse-cluster/。此外,所有你开始所需的内容都在我之前链接的仓库中。