Summarize Graph results using facets
Facets in Optimizely Graph provide powerful aggregation and summarization capabilities for your content.
Facets are metadata or attributes attached to edges (relationships) between nodes. They add extra context about the connection, like timestamps, weights, roles, or labels, without needing a separate node. For example, in a "user > rated > movie" relationship, a facet could store the rating score or date of rating.
When summarizing graph results, facets let you aggregate or filter based on these edge attributes. For example, you can:
- Summarize large datasets without retrieving all individual items
- Create filtering interfaces with counts for each filter option
- Analyze content distribution across different dimensions
- Build dynamic navigation based on actual content
Facets enrich relationships with meaningful details, and they let you generate summaries or insights from graph queries by aggregating or filtering on those attributes.
Facet types
One of the biggest advantages of facets is that you can use them to summarize and analyze graph data. The following facet types are available in Optimizely Graph:
String facets
Use string facets to group and count items based on exact string values. This is useful for categorizing content and understanding the distribution of different categories.
The following query groups articles by their categories and counts the number of articles in each category:
query ArticlesByCategory($categoryFilters: [String!]) {
ArticlePage {
facets {
Category {
Name(filters: $categoryFilters) {
name
count
}
}
}
total
}
}The following are some example variables:
{
"categoryFilters": ["Plan", "Meet", "Track"]
}The following is the response for the example query:
{
"data": {
"ArticlePage": {
"facets": {
"Category": {
"Name": [
{ "name": "Plan", "count": 2 },
{ "name": "Meet", "count": 1 },
{ "name": "Track", "count": 1 }
]
}
},
"total": 4
}
}
}Date facets
Use date facets to group content by specific date ranges. This is useful for tracking when content was published and analyzing trends over time.
The following query counts articles published on specific dates:
query ArticlesByPublishDate {
ArticlePage {
facets {
StartPublish(unit: DAY) {
name
count
}
}
total
}
}The following example response shows counts for articles published on each date:
{
"data": {
"ArticlePage": {
"facets": {
"StartPublish": [
{ "name": "2024-09-12", "count": 2 },
{ "name": "2024-09-11", "count": 1 },
{ "name": "2024-09-10", "count": 1 }
]
},
"total": 4
}
}
}Numeric facets
Use numeric facets to group and count items based on numeric attributes. Although Price fields are unavailable in the Alloy template, you can use Status facets as an alternative.
The following query counts articles by their publication status, such as Published or Draft:
query ArticlesByStatus {
ArticlePage {
facets {
Status {
name
count
}
}
total
}
}The following is the response to the example query:
{
"data": {
"ArticlePage": {
"facets": {
"Status": [
{ "name": "Published", "count": 4 },
{ "name": "Draft", "count": 0 }
]
},
"total": 4
}
}
}Combining facets with filters
Combining facets with filters lets you provide contextual summaries by narrowing down results to specific criteria.
The following query provides filtered results for specific categories, status breakdown, and publication timeline:
query TechnologyArticlesFacets($categories: [String!]) {
ArticlePage {
items {
Name
RelativePath
Category {
Name
}
}
facets {
# Get category distribution with filtering
Category {
Name(filters: $categories) {
name
count
}
}
# Get status distribution within Plan category
Status {
name
count
}
# Get publication date distribution
StartPublish(unit: DAY) {
name
count
}
}
total
}
}The following are some example variables:
{
"categories": ["Plan", "Meet", "Track"]
}Advanced faceting patterns
Multi-level facets
Multi-level facets create hierarchical summaries by organizing data into nested categories or levels.
The following query summarizes content by publication status across all content:
query ContentHierarchyFacets {
Content {
facets {
# Publication status across all content
Status {
name
count
}
}
total
}
}Advanced facets like _typeName, Category on generic Content, and metadata fields are not available in the Alloy template schema. What is going on with "on generic" here?
Geographic facets
Use geographic facets to group and count items based on location attributes. Although event-based content types are not available, you can use available content types for location-based summaries.
The following query provides a summary of content by category and status:
query ContentByCategory {
ArticlePage {
facets {
Category {
Name {
name
count
}
}
Status {
name
count
}
}
total
}
}Time-based analysis
Time-based analysis tracks content trends over time, helping you understand patterns and changes in content publication. Multiple facets on the same field require aliases, and advanced time filtering is not available in the current schema.
The following query analyzes daily publication activity to track content trends over time:
query ContentTrends {
ArticlePage {
facets {
# Daily publication activity
startPublishDaily: StartPublish(unit: DAY) {
name
count
}
}
total
}
}Build dynamic filter interfaces
Complete filter interface example
Building dynamic filter interfaces lets users interactively filter and explore content based on various criteria.
The following query builds a filter interface for articles based on category and publication date, letting users to explore content interactively:
query BuildFilterInterface($categoryFilter: String, $availableCategories: [String!]) {
ArticlePage(
where: {
Category: { Name: { eq: $categoryFilter } }
}
limit: 20
) {
items {
Name
RelativePath
StartPublish
Category {
Name
}
TeaserText
}
facets {
# Available categories (filtered to relevant options)
Category {
Name(filters: $availableCategories) {
name
count
}
}
# Publication timeline
StartPublish(unit: DAY) {
name
count
}
# Content status
Status {
name
count
}
}
total
}
}The following variables are available for filtered state:
{
"categoryFilter": "Plan",
"availableCategories": ["Plan", "Meet", "Track"]
}The following variables are available for unfiltered state:
{
"categoryFilter": null,
"availableCategories": ["Plan", "Meet", "Track"]
}Performance considerations
Facet optimization tips
- Use simple facet queries – Focus on necessary facets to improve performance.
query OptimizedFacets {
ArticlePage {
facets {
# Basic category facet
Category {
Name {
name
count
}
}
# Status facet
Status {
name
count
}
}
}
}- Focus on available fields – Use fields that exist in your schema.
query WorkingFacets {
ProductPage {
facets {
# Use fields that exist in the schema
Category {
Name {
name
count
}
}
}
}
}- Combine with
WHEREclauses – Scope facets to relevant data.
query ScopedFacets {
ArticlePage(
where: {
Status: { eq: "Published" }
}
) {
facets {
# Facets only on published content
Category {
Name {
name
count
}
}
}
}
}Real-world use cases
Content catalog with facets
Content catalogs with facets let users filter and explore a wide range of content efficiently.
The following query provides a content catalog with facets for filtering by search term and category:
query ContentCatalogWithFacets($searchTerm: String, $categoryFilter: String) {
ProductPage(
where: {
_and: [
{ Name: { contains: $searchTerm } }
{ Category: { Name: { eq: $categoryFilter } } }
]
}
limit: 24
) {
items {
Name
TeaserText
PageImage {
Url
}
Category {
Name
}
}
facets {
Category {
Name {
name
count
}
}
Status {
name
count
}
}
total
}
}Content dashboard analytics
Content dashboard analytics provide valuable insights into the distribution and status of content, enabling you to make informed decisions.
The following query provides content dashboard analytics by summarizing content status:
query ContentDashboard {
Content {
facets {
# Content status distribution
Status {
name
count
}
}
total
}
}Advanced metadata facets like _typeName, _modified, and _createdBy are not available in the Alloy template schema.
Article timeline with facets
Article timeline facets let you track and analyze the publication timeline of articles.
The following query retrieves articles along with their publication dates, categories, and statuses, letting you analyze the timeline and distribution of content:
query ArticleTimelineFacets {
ArticlePage {
items {
Name
StartPublish
RelativePath
Category {
Name
}
}
facets {
# Category distribution
Category {
Name {
name
count
}
}
# Publication dates
StartPublish(unit: DAY) {
name
count
}
# Status
Status {
name
count
}
}
total
}
}Best practices for facets
Optimizely recommends the following best practices when working with facets:
- Use facets for summarization – Instead of retrieving all items, use facets to get counts when you only need summary information. This approach improves performance and efficiency.
- Use the correct facet syntax – For complex fields, employ the nested structure. For example, use
Category { Name { name count } }to ensure accurate data retrieval and representation. - Use the
filtersparameter – Limit facet results to relevant values by using filters. For example,Name(filters: $categories)lets you focus on specific categories, enhancing the relevance of your results. - Combine facets with filters – Provide contextual summaries by combining facets with filters. This practice lets you tailor results to specific queries or user needs.
- Cache facet results – Facet results change less frequently than individual items. Cache them when possible to reduce server load and improve response times.
- Use available fields – Stick to fields that exist in your schema, such as
Category,Status, andStartPublish, to ensure compatibility and accuracy.
You should avoid making the following mistakes:
- Do not assume all parameters are supported – The
limitparameter is not available for facets, butfiltersis. Be mindful of the parameters you use to avoid errors. - Do not assume field availability – Fields like
ArticleAuthor,Tags,Price, andBrandmay not exist in your schema. Always verify field availability before using them. - Do not ignore empty facets – Handle cases where facets return no results gracefully. Implement logic to manage empty results to maintain a smooth user experience.
- Do not use incorrect field names – Use name and count for facet results instead of Name and Count. Correct field names ensure accurate data retrieval and display.
Error handling for facets
Proper error handling ensures your application can handle cases where facets return no results.
The following query retrieves category facets filtered by specified categories. It helps ensure that even if no categories match the filters, the application can handle the situation without errors.
query FacetsWithErrorHandling($categoryFilters: [String!]) {
ArticlePage {
facets {
# This might return empty if no categories exist
Category {
Name(filters: $categoryFilters) {
name
count
}
}
}
total
}
}The following JavaScript function processes the facet results and handles cases where the results might be empty:
function processFacetResults(facetData) {
const categories = facetData?.Category?.Name || [];
if (categories.length === 0) {
console.log('No categories found');
return [];
}
return categories.map(category => ({
label: category.name,
value: category.name,
count: category.count
}));
}Updated 1 day ago
