تشغيل استعلامات Data Explorer باستخدام Discourse API

:bookmark: يشرح هذا الدليل كيفية استخدام واجهة برمجة تطبيقات Discourse لإنشاء الاستعلامات وتشغيلها وإدارتها باستخدام المكون الإضافي Data Explorer.

:person_raising_hand: مستوى المستخدم المطلوب: مسؤول

يمكن تشغيل أي إجراء يمكن تنفيذه من خلال واجهة مستخدم Discourse تقريبًا باستخدام واجهة برمجة تطبيقات Discourse.

توفر هذه الوثيقة نظرة عامة شاملة لاستخدام واجهة برمجة التطبيقات بالتحديد بالاقتران مع المكون الإضافي Data Explorer.

للحصول على نظرة عامة عامة حول كيفية العثور على طلب واجهة برمجة التطبيقات الصحيح لإجراء ما، راجع: Reverse engineer the Discourse API .

تشغيل استعلام Data Explorer

لتشغيل استعلام Data Explorer عبر واجهة برمجة التطبيقات، قم بإجراء طلب POST إلى /admin/plugins/explorer/queries/<query-id>/run. يمكنك العثور على معرّف الاستعلام عن طريق زيارته عبر موقع Discourse الخاص بك والتحقق من المعلمة id في شريط العنوان.

فيما يلي مثال على استعلام بمعرّف 20 يُرجع المواضيع حسب عدد المشاهدات في تاريخ محدد:

--[params]
-- date :viewed_at

SELECT
topic_id,
COUNT(1) AS views_for_date
FROM topic_views
WHERE viewed_at = :viewed_at
GROUP BY topic_id
ORDER BY views_for_date DESC

يمكن تشغيل هذا الاستعلام من طرفية باستخدام:

curl -X POST "https://your-site-url/admin/plugins/explorer/queries/20/run" \
-H "Content-Type: multipart/form-data;" \
-H "Api-Key: <api-key>" \
-H "Api-Username: system" \
-F 'params={"viewed_at":"2019-06-10"}'

لاحظ أنك ستحتاج إلى استبدال <api-key> و <your-site-url> بمفتاح واجهة برمجة التطبيقات والنطاق الخاص بك.

التعامل مع مجموعات البيانات الكبيرة

يحد المكون الإضافي Data Explorer من النتائج بـ 1000 صف افتراضيًا. للتنقل عبر مجموعات البيانات الأكبر، يمكنك استخدام الاستعلام المثال أدناه:

--[params]
-- integer :limit = 100
-- integer :page = 0
SELECT * 
FROM generate_series(1, 10000)
OFFSET :page * :limit 
LIMIT :limit

لجلب النتائج صفحة بصفحة، قم بزيادة المعلمة page في الطلب:

curl -X POST "https://your-site-url/admin/plugins/explorer/queries/27/run" \
-H "Content-Type: multipart/form-data;" \
-H "Api-Key: <api-key>" \
-H "Api-Username: system" \
-F 'params={"page":"0"}'

توقف عندما يكون result_count صفرًا.

لمزيد من المعلومات حول التعامل مع مجموعات البيانات الكبيرة، راجع: Result Limits and Exporting Queries

إزالة بيانات relations من النتائج

عند تشغيل استعلامات Data Explorer من خلال واجهة المستخدم، تتم إضافة كائن relations إلى النتائج. تُستخدم هذه البيانات لعرض المستخدم في نتائج واجهة المستخدم، ولكن من غير المرجح أن تحتاج إليها عند تشغيل الاستعلامات عبر واجهة برمجة التطبيقات.

لإزالة تلك البيانات من النتائج، أضف المعلمة download=true مع طلبك:

curl -X POST "https://your-site-url/admin/plugins/explorer/queries/27/run" \
-H "Content-Type: multipart/form-data;" \
-H "Api-Key: <api-key>" \
-H "Api-Username: system" \
-F 'params={"page":"0"}' \
-F "download=true"

مصادقة واجهة برمجة التطبيقات

يمكن العثور على تفاصيل حول إنشاء مفتاح واجهة برمجة تطبيقات للطلبات هنا: Create and configure an API key .

إذا كان سيتم استخدام مفتاح واجهة برمجة التطبيقات فقط لتشغيل استعلامات Data Explorer، يمكنك تحديد “Granular” من القائمة المنسدلة Scope، ثم تحديد نطاق “run queries”.

الأسئلة الشائعة

هل هناك أي نقطة نهاية لواجهة برمجة التطبيقات يمكنني استخدامها للحصول على قائمة التقارير وأرقام المعرّفات؟ أريد إنشاء قائمة منسدلة تحتوي على القائمة؟

نعم، يمكنك إجراء طلب GET مصادق عليه إلى /admin/plugins/explorer/queries.json للحصول على قائمة بجميع الاستعلامات على الموقع.

هل من الممكن إنشاء استعلامات عبر واجهة برمجة التطبيقات؟

نعم. توجد وثائق حول كيفية القيام بذلك على Create a Data Explorer query using the API

هل من الممكن إرسال معلمات مع طلب النشر؟

نعم، قم بتضمين معلمات SQL باستخدام الخيار -F، كما هو موضح في الأمثلة.

هل يتم دعم تصدير CSV للاستعلامات بواسطة واجهة برمجة التطبيقات؟

على الرغم من أن إخراج JSON هو المعيار، يمكنك تحويل النتائج يدويًا إلى CSV. لم يعد تصدير CSV الأصلي مدعومًا.

موارد إضافية

39 إعجابًا
Watching API
"DataExplorer::ValidationError: Missing parameter end_date of type string
Get total list of topics and their view counts from Discourse API
Best API for All First Posts in a Category
Category API request downloads all topics
Reports by Discourse
TimeStamp of Tag
How can I get the list of Discourse Topic IDs dynamically
Passing params to Data Explorer using API requires enclosing a value
Get Latest topic for Current user
Getting recently updated posts using the REST API
`DataExplorer::ValidationError: Missing parameter` when running Data Explorer queries with [params] via API
`DataExplorer::ValidationError: Missing parameter` when running Data Explorer queries with [params] via API
Backend data retrieve for analytics
Discourse-user-notes API
Admin dashboard report reference guide
How to query the topics_with_no_response.json API with filters
Use API to get topics for a period using js
Access Discourse database with n8n
Why getUserById doesn't return the user's email?
Grant a custom badge through the API
Is there an API endpoint for recently edited posts
How to query gamification score via the API?
1.5X cheers on specific TL's or groups
Page Publishing
Identifying users in multiple groups using AND rather than OR?
Validation error even when parameter passed while running data explorer API with Curl
How to change the response default_limit in data explorer?
How to change the response default_limit in data explorer?
Order/Filter searched topics by latest update to First Post
API Filter users by emails, including secondary emails
Ability to have granular scope for data explorer?
Daily, weekly, or total stats by user over a specified time range
Looking for help posting automating data explorer reports to my forum
How to get all topics from a specific category using offset/page param in the API query?
Discourse 有哪个接口能直接获取某个帖子的最后一条评论信息
想得到活跃的用户——通过api
API endpoint to create invite links has moved to /invites.json
How to get a password from database?
Can I send an external URL to the Discourse API for it to return topics linking to that URL?
How to fetch posts/topics by multiple usernames
Restrict moderator access to only the stats panel on the admin dashboard?
How to get all the deleted posts for a specific topic
Discourse forum traffic query data
Download a user's posting history via Discourse API?
Discourse Data Explorer Query Response to Slack
Filter topics in category containing file attachments
Discord Integration with Webhooks
Download result of queries into Google Spreadsheet
Who's online "API"?
Is there any endpoint that would provide a user's external account IDs from their Discourse ID?
API post request without an Accept header returns 406
Best way to get (via API) a list of users from a group, and their bios
Create a Data Explorer query using the API
How to get a full list of badges of all users
API rate limits

يبدو أن هذا التعليق يشير إلى إمكانية تصدير CSV من واجهة برمجة التطبيقات (API). هل هذا ممكن؟ أنا فضولي فقط لأنني أحتاج البيانات بصيغة CSV. يمكنني دائمًا الحصول عليها بصيغة JSON وتحويلها إلى CSV ولكن إذا كانت هناك طريقة مدمجة للحصول على CSV فسيكون ذلك أسهل قليلاً.

هل من الممكن إجراء استعلام “مثل تم إنشاؤه أو تحديثه في آخر 50 ثانية”؟

:robot: الذكاء الاصطناعي يقول

-- [params]
-- int :seconds = 50

SELECT
    p.id AS post_id,
    p.created_at,
    p.updated_at,
    p.raw AS post_content,
    p.user_id,
    t.title AS topic_title,
    t.id AS topic_id
FROM posts p
INNER JOIN topics t ON t.id = p.topic_id
WHERE
    (EXTRACT(EPOCH FROM (NOW() - p.created_at)) <= :seconds
    OR EXTRACT(EPOCH FROM (NOW() - p.updated_at)) <= :seconds)
    AND p.deleted_at IS NULL
    AND t.deleted_at IS NULL
ORDER BY p.created_at DESC
LIMIT 50

لقد أجريت اختبارًا سريعًا، ويبدو أنه يعمل :slight_smile:

إعجاب واحد (1)

لا أرى “الإعجاب :heart:” الذي أضفته إلى منشور باستخدام استعلامك.

أعتقد أنك بحاجة إلى استخدام post_actions

--[params]
--string :timespan = 50 seconds

SELECT post_id,
       user_id,
       created_at,
       updated_at,
       deleted_at
FROM  post_actions
WHERE post_action_type_id=2 AND updated_at > NOW() - INTERVAL :timespan

إصدار بنتائج أجمل

--[params]
--string :timespan = 50 seconds
--boolean :include_in_timespan_deleted = false

SELECT
  post_id,
  user_id,
  CASE
    WHEN EXTRACT(EPOCH FROM (NOW() - created_at)) < 60 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - created_at))), ' seconds ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - created_at)) < 3600 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - created_at)) / 60), ' minutes ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - created_at)) < 86400 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - created_at)) / 3600), ' hours ago')
    ELSE CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - created_at)) / 86400), ' days ago')
  END AS relative_created_at,
  CASE
    WHEN EXTRACT(EPOCH FROM (NOW() - updated_at)) < 60 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - updated_at))), ' seconds ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - updated_at)) < 3600 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - updated_at)) / 60), ' minutes ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - updated_at)) < 86400 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - updated_at)) / 3600), ' hours ago')
    ELSE CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - updated_at)) / 86400), ' days ago')
  END AS relative_updated_at,
  CASE
    WHEN deleted_at IS NULL THEN 'no'
    WHEN EXTRACT(EPOCH FROM (NOW() - deleted_at)) < 60 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - deleted_at))), ' seconds ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - deleted_at)) < 3600 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - deleted_at)) / 60), ' minutes ago')
    WHEN EXTRACT(EPOCH FROM (NOW() - deleted_at)) < 86400 THEN CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - deleted_at)) / 3600), ' hours ago')
    ELSE CONCAT(ROUND(EXTRACT(EPOCH FROM (NOW() - deleted_at)) / 86400), ' days ago')
  END AS relative_deleted_at
FROM
  post_actions
WHERE
  post_action_type_id = 2
  AND updated_at > NOW() - INTERVAL :timespan
  AND (
    :include_in_timespan_deleted = false
    OR (deleted_at IS NOT NULL AND deleted_at > NOW() - INTERVAL :timespan)
  )

إعجابَين (2)

أوه، لقد قرأت خطأ! قرأت الجملة على أنها “هل من الممكن إجراء استعلام مثل ‘تم إنشاؤه أو تحديثه في آخر 50 ثانية’؟
(لاحظ موضع علامة الاقتباس المفردة)”

إعجاب واحد (1)

شكرا للجميع،

لقد نشرت هنا لأن ask.discourse وجهني إلى هذا المكان.
ما أبحث عنه هو ما إذا كانت واجهة برمجة التطبيقات (API) توفر هذه الإمكانية.

إعجاب واحد (1)

نعم بالطبع.
تقوم بإنشاء الاستعلام في مستكشف البيانات، ثم تقوم بتشغيل الاستعلام عبر واجهة برمجة التطبيقات (API) كما هو موضح في هذا الدليل.
لقد قمت للتو بتشغيل استعلام Moin عبر واجهة برمجة التطبيقات (API) وأعاد بشكل صحيح النتائج المتوقعة.

4 إعجابات

كنت أتساءل عن هذا أيضًا. هل JSON هو الطريقة الوحيدة لتصدير البيانات عبر واجهة برمجة التطبيقات أم أن تصدير CSV مدعوم أيضًا لـ Data Explorer؟

شكرا للجميع،

آسف على التأخير في الرد - كنت غير متصل بالإنترنت لبعض الوقت.

ما أفعله حاليًا هو البحث عن جميع المواضيع/المشاركات التي تم إنشاؤها اليوم، وتصفية المواضيع/المشاركات التي تم تحديثها قبل الطابع الزمني.

إعجاب واحد (1)

إذا كنت لا ترغب في القيام بذلك بنفسك، يمكنك سؤال الروبوت على ask.discourse.com. عادة ما يكون دقيقًا جدًا فيما يتعلق باستعلامات SQL المتعلقة بـ Discourse (ولكن لا تفترض أنه صحيح، تحقق من الكود للتأكد).

إعجاب واحد (1)

هل رأس Content-Type صحيح؟
في أدوات المطور، عند فحص استعلام مستكشف البيانات مع المعلمات، يظهر رأس Content-Type كالتالي:

Content-Type: application/x-www-form-urlencoded; charset=UTF-8

ومع ذلك، يتضمن أمر cURL الحالي:

-H "Content-Type: multipart/form-data;"


إعجاب واحد (1)
  • multipart/form-data
  • application/x-www-form-urlencoded
  • application/json

هي أنواع محتوى صالحة يمكنك استخدامها عند إجراء طلب واجهة برمجة التطبيقات.

إعجاب واحد (1)

@blake
language python
library requests
هل يمكنك تقديم استعلام استكشاف البيانات بنموذج API يتضمن ثلاثة معلمات
مرجع [الموضوع]( Passing params to Data Explorer using API requires enclosing a value ) الذي يقول إن المعلمات تحتاج إلى أن تكون محاطة بعلامات اقتباس مزدوجة بشكل صارم

بالتأكيد، إليك مثال باستخدام بايثون:

import json
import requests

API_KEY      = "YOUR_API_KEY"
API_USERNAME = "system"
QUERY_ID     = 20
SITE_URL     = "https://your-site-url"

# يجب أن تكون جميع القيم سلاسل نصية
params = {
    "user_id":   "2",
    "viewed_at": "2019-06-10",
    "limit":     "5"
}

# يتوقع مستكشف البيانات المعلمات كسلسلة نصية مشفرة بصيغة JSON
payload = {
    "params": json.dumps(params)
}

url = f"{SITE_URL}/admin/plugins/explorer/queries/{QUERY_ID}/run"
headers = {
    "Api-Key":       API_KEY,
    "Api-Username":  API_USERNAME,
    "Content-Type":  "application/json"
}

r = requests.post(url, headers=headers, json=payload)
r.raise_for_status()
print(r.json())
3 إعجابات