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.

Estoy probando todos los métodos que se me ocurren para descargar todos los temas y publicaciones de mi sitio: las opciones “más recientes” y “mejores” están limitadas, y ahora estoy intentando obtener todas las categorías y realizar una búsqueda por categoría (similar a como se hace en el sitio). Por ejemplo, en nuestro sitio, si busco “Q&A #q-aaquí, obtengo más de 50 resultados. Sin embargo, cuando busco esa misma cadena exacta usando la gem de Ruby discourse_api, solo obtengo 5:

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

¿Por qué esto no es consistente con la interfaz y con lo que se reporta? ¿Cuál es la forma más sencilla de exportar los datos? Me gustaría realizar algún análisis de procesamiento de lenguaje natural (NLP) sobre el contenido de nuestro sitio, pero resulta muy difícil simplemente obtener los datos. ¡Gracias!

latest utiliza paginación; solo necesitas pasar los parámetros correctamente y deberías poder acceder a todos los temas a través de la API.

La búsqueda también utiliza paginación.

Recomiendo Reverse engineer the Discourse API como un curso intensivo para averiguar todos los parámetros que necesitas.

¡Gracias @sam! Puedo ver (incluso desde la solicitud GET) que debería ser bastante intuitivo: cuando quiero obtener la página 2, agrego una opción adicional para la página. También veo que “options” es algo que puedo definir con la función discourse_api:

# frozen_string_literal: true
module DiscourseApi
  module API
    module Search
      # Devuelve los resultados de búsqueda que coinciden con el término especificado.
      #
      # @param term [String] un término de búsqueda
      # @param options [Hash] un conjunto personalizable de opciones
      # @option options [String] :type_filter Devuelve resultados del tipo especificado.
      # @return [Array] Devuelve los resultados como un array de Hashes.
      def search(term, options = {})
        raise ArgumentError.new("#{term} es obligatorio pero no se especificó") unless term
        raise ArgumentError.new("#{term} es obligatorio pero no se especificó") unless !term.empty?

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

Así que, probando esto, esperaría obtener resultados diferentes aquí para la página 1 y la 2. O mejor aún, hagamos un poco más de separación y usemos las páginas 1 y 3. La consulta es para todos los temas de Q&A:

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

Ahora, recuperemos las páginas 1 y 3 usando el cliente discourse_api:

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

Puedo examinar el primer tema de cada uno:

=> {"id"=>220, "title"=>"¿Por qué estoy superando la cuota?", "fancy_title"=>"¿Por qué estoy superando la cuota?", "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"=>"¿Por qué estoy superando la cuota?", "fancy_title"=>"¿Por qué estoy superando la cuota?", "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}

Son exactamente iguales, lo que creo que significa que la variable de página no está funcionando. Cuando inspecciono en las herramientas de desarrollo de Chrome, el punto se activa al hacer scroll hacia abajo (ya que los mensajes se cargan automáticamente en la ventana), y puedo confirmar que page=2 es el parámetro correcto:

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

O mejor aún, simplemente mira la lista de parámetros:

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

Esto no es un envío de formulario, así que no veo ningún “Form Data” como en el ejemplo.

¿Alguien tiene alguna sugerencia aquí? He probado lo que se sugirió, pero no veo un siguiente paso lógico. La variable ‘page’ no parece funcionar cuando se proporciona con la solicitud.

La gema de la API de Discourse utiliza la ruta /search/query. Parece que no responde a la paginación. La interfaz de usuario de Discourse utiliza la ruta /search. Esta sí responde a la paginación.

Puedes probar esto en tu navegador yendo a http://forum.example.com/search.json?q=test y luego intentando http://forum.example.com/search.json?q=test&page=2.

Es posible que necesites encontrar una forma de hacer la llamada a la API sin usar la gema de la API de Discourse. Si tu objetivo es obtener todos los temas y publicaciones de tu sitio, usar la ruta /search no parece ser el mejor enfoque.

Podrías intentar hacer una llamada a la API en http://forum.example.com/c/your-category-slug.json. Si no se devuelven todos los temas de la categoría en la solicitud, la propiedad topic_list de la solicitud tendrá una propiedad more_topics_url que te dará la ruta a la siguiente página de temas. Esto se verá algo así como "/c/site-feedback?page=2". Necesitarás agregar .json a la URL para obtener los datos JSON (/c/site-feedback.json?page=2).

¡Gracias! Eso funcionó perfectamente, y es mucho más fácil en Python con requests (lo estaba complicando a propósito para acostumbrarme más a Ruby, pero el cliente no tenía lo que necesitaba). Casi he terminado con las exportaciones y aún no he hecho nada de aprendizaje automático, pero si alguien está interesado en las llamadas que realicé, los scripts rápidos están aquí: GitHub - hpsee/discourse-cluster: Simple scripts to export posts for a discourse category, and do a clustering · GitHub. ¡Espero hacer algún agrupamiento genial pronto!

¡Gracias de nuevo, @sam y @simon! Por si a otros les interesa algún día hacer una exportación sencilla de los temas o, incluso, ir más allá y realizar agrupaciones con visualizaciones en D3, escribí una breve publicación que explica el proceso: AskCI Discourse Clustering | VanessaSaurus. Y, como ya mencioné, todo lo necesario para empezar está en el repositorio que enlacé anteriormente.