דלגו לתוכן

קיבוץ ופונקציות צבירה

Archie Core מציע יכולות קיבוץ וצבירה חזקות באמצעות ה-API של GraphQL. ניתן לקבץ רשומות לפי ערכי שדות, לחשב פונקציות צבירה (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 המייצגים את השדות לפייהם לקבץ. ערכי ה-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ספירת ערכים ייחודייםכן

ה-enum של 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: חייב להתאים ל-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: חייב להתאים ל-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מערך של אובייקטים, כל אחד מכיל את ערכי הצבירה המחושבים ממופתחים לפי alias

מערך aggregates מקביל ל-items — הצבירה באינדקס i מתאימה לקבוצה באינדקס i ב-items.

  • ערכי enum של GroupBy ו-AggregateField משתמשים באותיות גדולות של שם השדה ב-camelCase: payment_methodpaymentMethodPAYMENTMETHOD.
  • alias-ים של having חייבים להתאים ל-alias המוגדר ב-aggregateBy. אם לא תואמים, תנאי ה-having מתעלמים ממנו.
  • alias-ים של aggregateSort חייבים להתאים ל-alias המוגדר ב-aggregateBy.
  • COUNT ללא field משתמש ב-COUNT(*), סופר את כל השורות בקבוצה.
  • תנאי having מרובים ניתן לשלב — כולם חייבים להתקיים (לוגיקת AND).
  • רשומות aggregateSort מרובות מיושמות לפי סדר עדיפות (הראשונה היא המיון העיקרי).
  • ארגומנטי עימוד סטנדרטיים (first, skip, after, before) עובדים עם תוצאות מקובצות.
  • ארגומנט filter מיושם לפני קיבוץ (שווה ערך ל-SQL WHERE), בעוד ש-having מיושם אחרי קיבוץ (שווה ערך ל-SQL HAVING).