שאילתות GROQ ב-Sanity: מהבסיס לאופטימיזציה מתקדמת

מבני תוכן מורכבים ב-Sanity מובילים לעיתים קרובות לשאילתות איטיות ולבלגן כתוצאה מקריאות API מרובות. אנו מגדירים שאילתות GROQ על ידי שילוב שלבים לבקשה אחת יעילה. הצוות שלנו מספק את הפרויקט במפתח מלא—מביקורת ועד אופטימיזציה—תוך הבטחת ביצועים אמינים ותמיכה מתמשכת.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
שאילתות GROQ ב-Sanity: מהבסיס לאופטימיזציה מתקדמת
בינוני
מ- 1 יום עד 3 ימים

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אתר חברה B2B ADVANCE
    פיתוח אתר חברה B2B ADVANCE
    1502
  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1344
  • פיתוח אתר עבור BELFINGROUP
    פיתוח אתר עבור BELFINGROUP
    1052
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1307
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1049
  • פיתוח אתר לחברת FIXPER
    פיתוח אתר לחברת FIXPER
    1033

שאילתות GROQ ב-Sanity: מהיסודות ועד לאופטימיזציה מתקדמת

תארו לעצמכם: אתם בונים אתר headless עם Sanity ו-Next.js. מודל התוכן שלכם גדל—6 סוגי מסמכים, קשרים מורכבים, אזורים דינמיים. בעמוד הנחיתה הראשון, אתם נתקלים בתסכול: שאילתות N+1, שליפות מקוננות, ובלוק "מאמרים קשורים" שנטען ב-7 שניות. נתקלנו בזה בפרויקט פורטל מדיה גדול: זמן טעינה של 12 שניות, 47 בקשות נפרדות. הפתרון היה שאילתת GROQ אחת שקיצצה את הזמן ל-0.8 שניות. נשמע מוכר? טיפלנו בזה יותר מפעם אחת.

GROQ (Graph-Relational Object Queries) הוא לא REST, לא SQL, ולא GraphQL. הוא גמיש יותר מ-REST למבנים מורכבים: projections, חיבורים דרך ->, בחירות מותנות, אגרגציות—הכל בשאילתה אחת ללא בעיות N+1. הצוות שלנו, עם ניסיון של למעלה מחמש שנים ב-Sanity, כיוון עשרות פרויקטים, וקיצץ את עומס ה-API עד פי שלושה. במאמר זה, נראה לכם איך לכתוב שאילתות GROQ כראוי, להימנע מטעויות נפוצות, ולמטב מהירות.

למה GROQ במקום REST או GraphQL?

Sanity מציע API מסוג HTTP מחוץ לקופסה, אבל נקודות קצה מותאמות אישית לכל עמוד מובילות לכאוס. GROQ נותן לכם תחביר אחיד לכל שליפה. השוו:

קריטריון GROQ REST API GraphQL
שאילתות לעמוד 1 (מורכבת) 5–15 (מרובות) 1–3 (אבל N+1 עם pagination)
חיבור (resolve) מובנה -> דורש שאילתות נפרדות דורש batch loading
הקרנות מותנות מובנה _type == "..." => אין, חייבים לסנן בצד הלקוח כן, דרך fragments
אגרגציות (count, unique) פונקציות מובנות אין, צריך server hooks כן, אבל מורכב יותר

GROQ מהיר פי 2–3 בשליפת עמודים עם סוגי בלוקים מרובים—הוכח בפרויקטים שלנו.

איך לבצע נכון שאילתות Join ב-GROQ?

חיבורים ב-GROQ נעשים עם אופרטור ה-resolve ->. הוא מחליף JOINs רלציוניים ומאפשר לשלוף מסמכים קשורים ללא שאילתות נוספות. צעד אחר צעד:

  1. זיהוי שדה ההפניה (לדוגמה, author מסוג reference).
  2. שימוש ב--> אחרי השדה: author->{name}.
  3. הגבלת שדות עם projection כדי להימנע מטעינת נתונים מיותרים.

שאילתה אחת מחזירה פוסטים יחד עם נתוני המחבר:

*[_type == "post"]{ title, "author": author->{name, "avatar": image.asset->url} } 

הגבילו את עומק ה-resolve—שתיים עד שלוש רמות מספיקות בפועל.

מקרה בוחן: אופטימיזציה של זמן טעינת בלוג

לקוח הגיע אלינו עם בעיה: עמוד הבלוג שלו על Sanity + Next.js נטען ב-12 שניות. גילינו שעבור רשימת המאמרים, בוצעו 47 שאילתות נפרדות (כל פוסט שלף מחבר, קטגוריות, מאמרים קשורים ומטא-דאטה). הפתרון היה שאילתת GROQ אחת עם resolve ו-pagination:

*[_type == "post" && status == "published"] | order(publishedAt desc) [$start...$end] {
  _id,
  title,
  "slug": slug.current,
  publishedAt,
  "author": author->{
    name,
    "avatar": image.asset->url
  },
  "categories": categories[]->{
    title,
    "slug": slug.current
  },
  "excerpt": string::slice(pt::text(body), 0, 200)
}
count(*[_type == "post" && status == "published"])

תוצאה: שאילתה אחת, 0.8 שניות במקום 12. בנוסף, בונוס—ספירת המאמרים הכוללת ל-pagination. אנחנו בונים אופטימיזציות כאלה לתוך סט השאילתות הסטנדרטי שלנו.

מה כלול בהקמת שאילתות GROQ

אנחנו מציעים פיתוח turnkey—מביקורת ועד תיעוד. החבילה כוללת:

  • ניתוח מודל התוכן שלכם וזיהוי צווארי בקבוק (N+1, שאילתות מיותרות)
  • עיצוב שאילתות אוניברסליות ל-4–6 סוגי עמודים: דפי נחיתה, רשימות, כרטיסי פרטים, חיפוש
  • יישום עם טיפוסי TypeScript—כל שאילתה עטופה בתג groq שמחזיר את הטיפוס הנכון
  • אופטימיזציה דרך projections, resolve ואגרגציות—payload מינימלי
  • אינטגרציה עם Sanity Vision לניפוי באגים ובדיקות
  • הדרכת צוות—תיעוד ותבניות נמסרים

הסט הסטנדרטי מכסה תחביר בסיסי, שאילתות עם פרמטרים, Portable Text, pagination, חיפוש טקסט מלא עם Algolia (אם צריך), וחיפושים הפוכים (refs). הכל נבדק על 30+ פרויקטים.

טעויות נפוצות בכתיבת GROQ
  • שרשור מחרוזות במקום פרמטרים—סיכון ל-injection, ללא caching. תמיד השתמשו ב-*[_type == "post"]{ title, "author": author->{name, "avatar": image.asset->url} } .
  • עומק resolve מופרז—יותר משלוש רמות פוגע בביצועים. היצמדו ל-2–3.
  • התעלמות מ-*[_type == "post" && status == "published"] | order(publishedAt desc) [$start...$end] { _id, title, "slug": slug.current, publishedAt, "author": author->{ name, "avatar": image.asset->url }, "categories": categories[]->{ title, "slug": slug.current }, "excerpt": string::slice(pt::text(body), 0, 200) } count(*[_type == "post" && status == "published"]) בבדיקת שדות—שדות יכולים להיות null ב-Sanity.
  • חוסר pagination ברשימות מעל 100 פריטים. השתמשו ב-$variable.
  • שכחת ה-count—החזירו גם מערך וגם ספירה בו-זמנית.

דוגמה: סט שאילתות מלא (עם טיפוסים)

import { createClient } from '@sanity/client'
import { groq } from 'next-sanity'

const postQuery = groq`
  *[_type == "post" && slug.current == $slug][0] {
    _id,
    title,
    "slug": slug.current,
    publishedAt,
    body,
    "author": author->{ name, "image": image.asset->url },
    "relatedPosts": *[_type == "post" && references(^.categories[]._ref) && _id != ^._id] | order(publishedAt desc) [0...3] {
      title,
      "slug": slug.current
    }
  }
`

type PostResult = {
  _id: string
  title: string
  slug: string
  publishedAt: string
  body: any[]
  author: { name: string; image: string }
  relatedPosts: { title: string; slug: string }[]
}

const post = await client.fetch<PostResult>(postQuery, { slug: params.slug })

תיעוד מלא של GROQ זמין באתר הרשמי של Sanity. אם אתם רוצים לזרז פיתוח—המהנדסים שלנו מוכנים לעזור בהקמה. צרו קשר כדי לדון בפרויקט שלכם ולמצוא את הפתרון האופטימלי. קבלו ייעוץ ממהנדס Sanity.

לוח זמנים ועלות

פיתוח סט שאילתות אורך יום עד שלושה ימים תלוי במורכבות המודל. העלות נקבעת באופן אישי. אנחנו לא מסתירים מספרים: פנו אלינו—נעריך את הפרויקט שלכם ביום עסקים אחד. אנחנו מבטיחים שהשאילתות יהיו מותאמות ל-Core Web Vitals ולא יגרמו לבעיות N+1.