---
title: Summarize Optimizely Graph results using facets
slug: graph/docs/summarize-optimizely-graph-results-using-facets
docTags: 
createdAt: 2026-07-30T20:30:20.147Z
---

Facets are metadata or attributes attached to edges (relationships) between nodes. They add context to the connection, such as timestamps, weights, roles, or labels, without requiring a separate node. For example, in a `user > rated > movie` relationship, a facet can store the rating score or the date of the rating.

When summarizing Optimizely Graph results, facets let you aggregate or filter based on these edge attributes. For example, you can do the following:

- 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 let you generate summaries or insights from Optimizely Graph queries by aggregating or filtering on those attributes.

## Facet types

You can use facets to summarize and analyze graph data. The following facet types are available in Optimizely Graph:

- [String facets](docId\:EuKwkel6IZ5SE75TvOORS).
- [Date facets](docId\:EuKwkel6IZ5SE75TvOORS).
- [Numeric facets](docId\:EuKwkel6IZ5SE75TvOORS).

### 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:

```graphql
query ArticlesByCategory($categoryFilters: [String!]) {
  ArticlePage {
    facets {
      Category {
        Name(filters: $categoryFilters) {
          name
          count
        }
      }
    }
    total
  }
}
```

The following are example variables:

```json
{
  "categoryFilters": ["Plan", "Meet", "Track"]
}
```

The following is the response for the example query:

```json
{
  "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 for analyzing trends over time.

The following query counts articles published on specific dates:

```graphql
query ArticlesByPublishDate {
  ArticlePage {
    facets {
      StartPublish(unit: DAY) {
        name
        count
      }
    }
    total
  }
}
```

The following example response shows the counts for articles published on each date:

```json
{
  "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.

The following query counts articles by their publication status, such as `Published` or `Draft`:

```graphql
query ArticlesByStatus {
  ArticlePage {
    facets {
      Status {
        name
        count
      }
    }
    total
  }
}
```

The following is the response to the example query:

```json
{
  "data": {
    "ArticlePage": {
      "facets": {
        "Status": [
          { "name": "Published", "count": 4 },
          { "name": "Draft", "count": 0 }
        ]
      },
      "total": 4
    }
  }
}
```

## Combine 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, a status breakdown, and a publication timeline:

```graphql
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 the Plan category
      Status {
        name
        count
      }
      
      # Get publication date distribution
      StartPublish(unit: DAY) {
        name
        count
      }
    }
    total
  }
}
```

The following are example variables:

```json
{
  "categories": ["Plan", "Meet", "Track"]
}
```

## Advanced facet 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:

```graphql
query ContentHierarchyFacets {
  Content {
    facets {
      # Publication status across all content
      Status {
        name
        count
      }
    }
    total
  }
}
```

### 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 existing content types for location-based summaries.

The following query provides a summary of content by category and status:

```graphql
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:

```graphql
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 you 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 you explore content interactively:

```graphql
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 the filtered state:

```json
{
  "categoryFilter": "Plan",
  "availableCategories": ["Plan", "Meet", "Track"]
}
```

The following variables are available for the unfiltered state:

```json
{
  "categoryFilter": null,
  "availableCategories": ["Plan", "Meet", "Track"]
}
```

## Performance considerations

### Facet optimization tips

- **Use simple facet queries** – Focus on necessary facets to improve performance.

```graphql
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.

```graphql
query WorkingFacets {
  ProductPage {
    facets {
      # Use fields that exist in the schema
      Category {
        Name {
          name
          count
        }
      }
    }
  }
}
```

- **Combine with** `where` **clauses** – Scope facets to relevant data.

```graphql
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 you 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:

```graphql
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, letting you make informed decisions.

The following query provides content dashboard analytics by summarizing content status:

```graphql
query ContentDashboard {
  Content {
    facets {
      # Content status distribution
      Status {
        name
        count
      }
    }
    total
  }
}
```

### 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:

```graphql
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 obtain counts when you only need summary information. This approach improves performance and efficiency.
- **Use the correct facet syntax** – For complex fields, use the nested structure. For example, use `Category { Name { name count } }` to ensure accurate data retrieval and representation.
- **Use the** `filters` **parameter** – 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** – Use fields that exist in your schema, such as `Category`, `Status`, and `StartPublish`, to ensure compatibility and accuracy.

Avoid the following mistakes:

- **Do not assume all parameters are supported** – The `limit` parameter is not available for facets, but `filters` is. Be mindful of the parameters you use to avoid errors.
- **Do not assume field availability** – Fields such as `ArticleAuthor`, `Tags`, `Price`, and `Brand` may not exist in your schema. 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.

### Handle errors for facets

Proper error handling ensures that 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.

```graphql
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:

```javascript
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
  }));
}
```
