تخطَّ إلى المحتوى

التجميع والدوال التجميعية

يوفر Archie Core إمكانيات قوية للتجميع والدوال التجميعية من خلال واجهة GraphQL API. يمكنك تجميع السجلات حسب قيم الحقول، وحساب دوال التجميع (COUNT، SUM، AVG، MIN، MAX، COUNT_DISTINCT)، وتصفية المجموعات بشروط HAVING، وترتيب النتائج حسب القيم المجمعة.

عند استخدام التجميع والدوال التجميعية، تتوفر الوسائط التالية في أي استعلام قائمة:

الوسيطالنوعالوصف
groupBy[{TableName}GroupBy]الحقول التي يتم تجميع النتائج وفقاً لها
aggregateBy[{TableName}AggregateInput]دوال التجميع المراد حسابها
having[{TableName}HavingFilterInput]تصفية المجموعات حسب نتائج التجميع
aggregateSort[{TableName}AggregateSortInput]ترتيب النتائج حسب القيم المجمعة

يمكن دمج هذه الوسائط مع وسائط قياسية مثل filter وfirst وskip وorderBy.

يقبل وسيط groupBy مصفوفة من قيم التعداد (enum) تمثل الحقول التي يتم التجميع وفقاً لها. تتبع قيم التعداد النمط: اسم الحقل بصيغة camelCase محولاً إلى أحرف كبيرة.

اتفاقية التسمية:

اسم العمود (DB)اسم الحقل (GraphQL)قيمة enum لـ GroupBy
payment_methodpaymentMethodPAYMENTMETHOD
created_atcreatedAtCREATEDAT
statusstatusSTATUS
category_idcategoryIdCATEGORYID

مثال: تجميع الطلاب حسب الحالة النشطة

Section titled “مثال: تجميع الطلاب حسب الحالة النشطة”

الطلب

query {
students(groupBy: [ISACTIVE]) {
items {
isActive
}
count
}
}

الاستجابة

{
"data": {
"students": {
"items": [
{ "isActive": true },
{ "isActive": false }
],
"count": 2
}
}
}

يتيح وسيط aggregateBy حساب دوال التجميع على البيانات المجمعة (أو غير المجمعة). يتطلب كل تجميع function وfield اختياري وalias إلزامي.

input {TableName}AggregateInput {
function: AggregateFunction!
field: {TableName}AggregateField
alias: String!
}
الدالةالوصفهل field مطلوب؟
COUNTعد الصفوفلا (يستخدم COUNT(*) عند الحذف)
SUMجمع القيم الرقميةنعم
AVGحساب المتوسطنعم
MINإيجاد القيمة الدنيانعم
MAXإيجاد القيمة العليانعم
COUNT_DISTINCTعد القيم المميزةنعم

يتبع تعداد field نفس اتفاقية الأحرف الكبيرة مثل GroupBy.

alias هو سلسلة تختارها لتسمية النتيجة. تظهر كمفتاح في كائن الاستجابة aggregates.

مثال: عد ومتوسط عمر الطلاب المجمعين حسب الحالة النشطة

Section titled “مثال: عد ومتوسط عمر الطلاب المجمعين حسب الحالة النشطة”

الطلب

query {
students(
groupBy: [ISACTIVE]
aggregateBy: [
{ function: COUNT, alias: "totalStudents" }
{ function: AVG, field: AGE, alias: "avgAge" }
]
) {
items {
isActive
}
count
aggregates
}
}

الاستجابة

{
"data": {
"students": {
"items": [
{ "isActive": true },
{ "isActive": false }
],
"count": 2,
"aggregates": [
{ "totalStudents": 5, "avgAge": 23.4 },
{ "totalStudents": 2, "avgAge": 21.0 }
]
}
}
}

كل إدخال في مصفوفة aggregates يقابل المجموعة في نفس الفهرس في items.

يصفّي وسيط having المجموعات حسب نتائج التجميع، بما يعادل جملة SQL HAVING. يستخدم نوع إدخال مخصص بثلاثة حقول.

input {TableName}HavingFilterInput {
alias: String!
operator: HavingOperator!
value: Float!
}
  • alias: يجب أن يطابق الاسم المستعار المعرّف في aggregateBy.
  • operator: عامل المقارنة (انظر الجدول أدناه).
  • value: العتبة الرقمية للمقارنة ضدها.
العاملالمعادل في SQL
EQUALS=
NOT_EQUALS!=
GREATER_THAN>
GREATER_THAN_OR_EQUAL>=
LESS_THAN<
LESS_THAN_OR_EQUAL<=

مثال: المدن التي تضم أكثر من 3 طلاب

Section titled “مثال: المدن التي تضم أكثر من 3 طلاب”

الطلب

query {
students(
groupBy: [CITYID]
aggregateBy: [
{ function: COUNT, alias: "studentCount" }
]
having: [
{ alias: "studentCount", operator: GREATER_THAN, value: 3 }
]
) {
items {
cityId
}
count
aggregates
}
}

الاستجابة

{
"data": {
"students": {
"items": [
{ "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" }
],
"count": 1,
"aggregates": [
{ "studentCount": 5 }
]
}
}
}

تُعاد فقط المجموعات التي تحقق شرط التجميع.

يرتب وسيط aggregateSort النتائج المجمعة حسب قيمة مجمعة، بدلاً من حقل عادي.

input {TableName}AggregateSortInput {
alias: String!
direction: SortDirection!
}
  • alias: يجب أن يطابق الاسم المستعار المعرّف في aggregateBy.
  • direction: ASC (تصاعدي) أو DESC (تنازلي).

مثال: أفضل 3 مدن حسب عدد الطلاب

Section titled “مثال: أفضل 3 مدن حسب عدد الطلاب”

الطلب

query {
students(
groupBy: [CITYID]
aggregateBy: [
{ function: COUNT, alias: "studentCount" }
]
aggregateSort: [
{ alias: "studentCount", direction: DESC }
]
first: 3
) {
items {
cityId
}
count
aggregates
}
}

الاستجابة

{
"data": {
"students": {
"items": [
{ "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" },
{ "cityId": "0174dc55-d494-4ebc-a0e9-13575461cad4" },
{ "cityId": "a2b3c4d5-e6f7-8901-2345-678901234567" }
],
"count": 3,
"aggregates": [
{ "studentCount": 5 },
{ "studentCount": 3 },
{ "studentCount": 2 }
]
}
}
}

يمكنك دمج filter وgroupBy وaggregateBy وhaving وaggregateSort وfirst في استعلام واحد للتحليلات المعقدة.

مثال: أفضل 5 مدن للطلاب النشطين بمتوسط عمر فوق 20، مرتبة حسب متوسط العمر

Section titled “مثال: أفضل 5 مدن للطلاب النشطين بمتوسط عمر فوق 20، مرتبة حسب متوسط العمر”

الطلب

query {
students(
filter: { isActive: { equals: true } }
groupBy: [CITYID]
aggregateBy: [
{ function: COUNT, alias: "studentCount" }
{ function: AVG, field: AGE, alias: "avgAge" }
{ function: MAX, field: AGE, alias: "maxAge" }
]
having: [
{ alias: "avgAge", operator: GREATER_THAN, value: 20 }
]
aggregateSort: [
{ alias: "avgAge", direction: DESC }
]
first: 5
) {
items {
cityId
}
count
aggregates
}
}

الاستجابة

{
"data": {
"students": {
"items": [
{ "cityId": "e14638cb-6d72-4a36-b30f-9b763136a7bb" },
{ "cityId": "0174dc55-d494-4ebc-a0e9-13575461cad4" }
],
"count": 2,
"aggregates": [
{ "studentCount": 3, "avgAge": 24.3, "maxAge": 28 },
{ "studentCount": 2, "avgAge": 22.5, "maxAge": 25 }
]
}
}
}

هذا الاستعلام:

  1. يصفّي الطلاب النشطين فقط (filter).
  2. يجمع حسب المدينة (groupBy).
  3. يحسب العدد ومتوسط العمر والحد الأقصى للعمر في كل مجموعة (aggregateBy).
  4. يحتفظ فقط بالمجموعات التي متوسط عمرها فوق 20 (having).
  5. يرتب حسب متوسط العمر تنازلياً (aggregateSort).
  6. يحدّ بأفضل 5 مجموعات (first).

عند استخدام التجميع، تتبع الاستجابة نوع Connection القياسي مع حقل إضافي aggregates:

الحقلالنوعالوصف
items[{TableName}!]!السجلات المجمعة (واحد لكل مجموعة، مع قيم الحقول المجمعة)
countInt!عدد المجموعات المُعادة
pageInfoPageInfo!معلومات التقسيم (hasNextPage، hasPreviousPage)
aggregatesJSONمصفوفة من الكائنات، كل واحد يحتوي على القيم المجمعة المحسوبة مفهرسة بالاسم المستعار

مصفوفة aggregates موازية لـ items — التجميع في الفهرس i يقابل المجموعة في الفهرس i في items.

  • قيم enum لـ GroupBy و AggregateField تستخدم الأحرف الكبيرة لاسم الحقل بصيغة camelCase: payment_methodpaymentMethodPAYMENTMETHOD.
  • يجب أن تطابق أسماء having المستعارة اسماً مستعاراً معرّفاً في aggregateBy. إذا لم تتطابق، يتم تجاهل شرط having.
  • يجب أن تطابق أسماء aggregateSort المستعارة اسماً مستعاراً معرّفاً في aggregateBy.
  • COUNT بدون field يستخدم COUNT(*)، عد جميع الصفوف في المجموعة.
  • يمكن دمج شروط having متعددة — يجب استيفاء الكل (منطق AND).
  • تُطبّق إدخالات aggregateSort المتعددة بترتيب الأولوية (الأول هو الترتيب الرئيسي).
  • وسائط التقسيم القياسية (first، skip، after، before) تعمل مع النتائج المجمعة.
  • وسيط filter يُطبّق قبل التجميع (يعادل SQL WHERE)، بينما having يُطبّق بعد التجميع (يعادل SQL HAVING).