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.

Estou tentando de todas as formas que consigo imaginar para baixar todos os tópicos e posts do meu site — os de mais recentes e os principais são limitados, e agora estou tentando obter todas as categorias e fazer uma busca por categoria (semelhante ao que posso fazer no site). Por exemplo, no nosso site, se eu buscar por Q&A #q-a aqui, obtenho mais de 50 resultados. Quando faço a busca pela mesma string exata usando a gem discourse_api do Ruby, obtenho apenas 5:

irb(main):123:0> topics["posts"].length
=> 5
irb(main):124:0> topics["topics"].length
=> 5

Por que isso não é consistente com a interface e com o que está sendo relatado? Qual é a maneira mais fácil de exportar os dados? Gostaria de fazer algum processamento de linguagem natural (NLP) no conteúdo do nosso site, mas está sendo muito difícil apenas obter os dados. Obrigado!

O endpoint latest faz paginação; você só precisa passar os parâmetros corretamente e conseguirá acessar todos os tópicos via API.

A busca também faz paginação.

Recomendo Reverse engineer the Discourse API como um curso intensivo para descobrir todos os parâmetros necessários.

Obrigado @sam! Consigo ver (mesmo pela requisição GET) que deve ser bastante intuitivo: quando quero obter a página 2, adiciono uma opção adicional para page. Também consigo ver que “options” é algo que posso definir com a função discourse_api:

# frozen_string_literal: true
module DiscourseApi
  module API
    module Search
      # Retorna resultados de busca que correspondem ao termo especificado.
      #
      # @param term [String] um termo de busca
      # @param options [Hash] Um conjunto personalizável de opções
      # @option options [String] :type_filter Retorna resultados do tipo especificado.
      # @return [Array] Retorna os resultados como um array de Hashes.
      def search(term, options = {})
        raise ArgumentError.new("#{term} é obrigatório, mas não foi especificado") unless term
        raise ArgumentError.new("#{term} é obrigatório, mas não foi especificado") unless !term.empty?

        response = get('/search/query', options.merge(term: term))
        response[:body]
      end
    end
  end
end

Então, ao testar isso, esperaria obter resultados diferentes aqui para a página 1 e a página 2. Ou, para dar um pouco mais de separação, vamos usar as páginas 1 e 3. A consulta é para todos os tópicos de Perguntas e Respostas:

 query = category["name"] + " #" + category["slug"]
=> "Q&A #q-a"

Agora, vamos recuperar as páginas 1 e 3 usando o cliente discourse_api:

topics1 = client.search(query, options={"page": "1"})
topics3 = client.search(query, options={"page": "3"})

Posso verificar o primeiro tópico de cada um:

=> {"id"=>220, "title"=>"Por que estou excedendo a cota?", "fancy_title"=>"Por que estou excedendo a cota?", "slug"=>"por-que-estou-excedendo-a-cota", "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"=>"Por que estou excedendo a cota?", "fancy_title"=>"Por que estou excedendo a cota?", "slug"=>"por-que-estou-excedendo-a-cota", "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}

Eles são exatamente iguais, o que, acredito, significa que a variável page não está funcionando? Quando inspeciono no Chrome DevTools, o ponto é acionado ao rolar para baixo (já que os posts são carregados automaticamente na janela), e posso confirmar que page=2 é o parâmetro correto:

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

ou, melhor ainda, basta olhar a lista de parâmetros:

Query String Parameters
q: Q&A #q-a
page: 2

Isso não é um envio de formulário, então não vejo nenhum “Form Data” conforme o exemplo.

Alguém tem alguma orientação aqui? Já tentei o que foi sugerido, mas não vejo um próximo passo lógico. A variável ‘page’ não parece estar funcionando quando passada na requisição.

O gem da API do Discourse está usando a rota /search/query. Ela não parece responder à paginação. A interface do Discourse usa a rota /search. Ela responde à paginação.

Você pode testar isso no seu navegador acessando http://forum.example.com/search.json?q=test e depois tentando http://forum.example.com/search.json?q=test&page=2.

Talvez você precise encontrar uma maneira de fazer a chamada da API sem usar o gem da API do Discourse. Se o seu objetivo é obter todos os tópicos e posts do seu site, usar a rota /search não parece ser a melhor abordagem.

Você pode tentar fazer uma chamada da API para http://forum.example.com/c/your-category-slug.json. Se todos os tópicos da categoria não forem retornados na solicitação, a propriedade topic_list da solicitação terá uma propriedade more_topics_url que fornecerá a rota para a próxima página de tópicos. Isso se parecerá com algo como "/c/site-feedback?page=2". Você precisará adicionar .json à URL para obter os dados JSON (/c/site-feedback.json?page=2).

Obrigado! Funcionou perfeitamente, e é muito mais fácil em Python com requests (eu estava dificultando de propósito para me acostumar mais com o Ruby, mas o cliente não tinha o que eu precisava). Estou quase finalizando as exportações e ainda não fiz nada relacionado a aprendizado de máquina, mas se alguém estiver interessado nas chamadas que fiz, os scripts rápidos estão aqui: GitHub - hpsee/discourse-cluster: Simple scripts to export posts for a discourse category, and do a clustering · GitHub. Espero fazer algum agrupamento legal em breve!

Obrigado novamente, @sam e @simon — caso outros algum dia se interessem em fazer uma exportação simples de tópicos ou (avançar) e realizar algum agrupamento com visualizações em d3, escrevi um post rápido que explica o processo: AskCI Discourse Clustering | VanessaSaurus. E, novamente, tudo o que você precisa para começar está no repositório que linkei anteriormente.