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.

J’essaie toutes les méthodes qui me viennent à l’esprit pour télécharger tous les sujets et tous les messages de mon site : les options « derniers » et « populaires » sont limitées, et je tente maintenant de récupérer toutes les catégories, puis d’effectuer une recherche par catégorie (comme on peut le faire sur le site). Par exemple, sur notre site, si je recherche « Q&A #q-a » ici, j’obtiens plus de 50 résultats. Lorsque je recherche exactement la même chaîne avec la gemme Ruby discourse_api, je n’obtiens que 5 résultats :

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

Pourquoi cette incohérence avec l’interface et avec ce que vous indiquez ? Quelle est la méthode la plus simple pour exporter les données ? Je souhaiterais effectuer une analyse NLP sur le contenu de notre site, mais il s’avère très difficile de simplement récupérer ces données. Merci !

« latest » prend en charge la pagination ; il vous suffit de transmettre correctement les paramètres pour pouvoir accéder à tous les sujets via l’API.

La recherche prend également en charge la pagination.

Je recommande Reverse engineer the Discourse API comme un guide rapide pour déterminer tous les paramètres nécessaires.

Merci @sam ! Je vois (même à partir de la requête GET) que cela devrait être assez intuitif : lorsque je veux obtenir la page 2, j’ajoute une option supplémentaire pour la page. Je vois aussi que “options” est quelque chose que je peux définir avec la fonction discourse_api :

# frozen_string_literal: true
module DiscourseApi
  module API
    module Search
      # Retourne les résultats de recherche correspondant au terme spécifié.
      #
      # @param term [String] un terme de recherche
      # @param options [Hash] un ensemble d'options personnalisables
      # @option options [String] :type_filter Retourne les résultats du type spécifié.
      # @return [Array] Retourne les résultats sous forme de tableau de Hash.
      def search(term, options = {})
        raise ArgumentError.new("#{term} est requis mais non spécifié") unless term
        raise ArgumentError.new("#{term} est requis mais non spécifié") unless !term.empty?

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

Donc, en essayant cela, je m’attendrais à obtenir des résultats différents pour la page 1 et la page 2. Ou pour mieux séparer, prenons les pages 1 et 3. La requête concerne tous les sujets Q&A :

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

Maintenant, récupérons les pages 1 et 3 en utilisant le client discourse_api :

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

Je peux examiner le premier sujet pour chacun :

=> {"id"=>220, "title"=>"Pourquoi dépasse-je le quota ?", "fancy_title"=>"Pourquoi dépasse-je le quota ?", "slug"=>"pourquoi-depasse-je-le-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"=>"Pourquoi dépasse-je le quota ?", "fancy_title"=>"Pourquoi dépasse-je le quota ?", "slug"=>"pourquoi-depasse-je-le-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}

Ils sont exactement identiques, ce qui signifie, je pense, que la variable de page ne fonctionne pas ? Lorsque j’inspecte dans les outils de développement de Chrome, le point est déclenché en faisant défiler vers le bas (puisque les messages se chargent automatiquement dans la fenêtre), je peux confirmer que page=2 est le bon paramètre :

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 mieux, regardons simplement la liste des paramètres :

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

Il ne s’agit pas d’un envoi de formulaire, donc je ne vois aucun “Form Data” comme dans l’exemple.

Quelqu’un a-t-il des conseils à ce sujet ? J’ai essayé ce qui a été suggéré, mais je ne vois pas d’étape logique suivante. La variable de page ne semble pas fonctionner lorsqu’elle est fournie avec la requête.

Le gem de l’API Discourse utilise la route /search/query. Elle ne semble pas prendre en charge la pagination. L’interface utilisateur de Discourse utilise la route /search. Elle prend en charge la pagination.

Vous pouvez tester cela dans votre navigateur en accédant à http://forum.example.com/search.json?q=test, puis en essayant http://forum.example.com/search.json?q=test&page=2.

Vous devrez peut-être trouver un moyen d’effectuer l’appel API sans utiliser le gem de l’API Discourse. Si votre objectif est de récupérer tous les sujets et messages de votre site, l’utilisation de la route /search ne semble pas être la meilleure approche.

Vous pouvez essayer d’effectuer un appel API vers http://forum.example.com/c/votre-slug-de-categorie.json. Si tous les sujets de la catégorie ne sont pas retournés dans la requête, la propriété topic_list de la requête contiendra une propriété more_topics_url qui vous donnera l’URL vers la page suivante des sujets. Cela ressemblera à quelque chose comme "/c/avis-du-site?page=2". Vous devrez ajouter .json à l’URL pour obtenir les données JSON (/c/avis-du-site.json?page=2).

Merci ! Ça a fonctionné parfaitement, et c’est tellement plus simple en Python avec requests (je me compliquais la tâche exprès pour me familiariser davantage avec Ruby, mais le client ne contenait pas ce dont j’avais besoin). J’ai presque terminé les exports et je n’ai pas encore fait de travaux de machine learning, mais si quelqu’un s’intéresse aux appels que j’ai effectués, les scripts rapides sont ici : GitHub - hpsee/discourse-cluster: Simple scripts to export posts for a discourse category, and do a clustering · GitHub. J’espère réaliser bientôt un clustering intéressant !

Encore merci @sam et @simon - au cas où d’autres seraient un jour intéressés soit par une exportation simple de sujets, soit (en allant plus loin) par un regroupement avec des visualisations en d3, j’ai rédigé un article rapide qui explique la démarche : AskCI Discourse Clustering | VanessaSaurus. Et encore une fois, tout ce dont vous avez besoin pour commencer se trouve dans le dépôt que j’ai précédemment lié.