---
title: Search content
slug: graph/docs/search-content
docTags: 
createdAt: 2026-07-30T20:30:18.526Z
---

Optimizely Graph provides full-text search using the `match` operator. Sort results with traditional relevance-based algorithms or with semantic search powered by AI.

## `match` operator

The `match` operator searches full-text fields across content stored in Optimizely Graph. It supports multiple ranking modes and can be combined with filters, boosting, and facets.

## Ranking modes

### Relevance

Use relevance ranking for keyword-based searches. It uses traditional algorithms such as [TF-IDF](https://en.wikipedia.org/wiki/Tf–idf) and [BM25](https://en.wikipedia.org/wiki/Okapi_BM25). Relevance ranking is fast, predictable, and works well with exact matches.

### Semantic

Use semantic ranking for natural-language queries. It uses AI models to understand meaning and context. Semantic ranking understands synonyms, intent, and related concepts, which makes it suitable for user questions and conceptual searches.

### When to use each ranking type

| Use case                | Recommended ranking | Reason                                    |
| ----------------------- | ------------------- | ----------------------------------------- |
| Product catalog search  | Relevance           | Exact matches for product names and SKUs. |
| Technical documentation | Relevance           | Matches precise terminology.              |
| Category browsing       | Relevance           | Matches categories and tags.              |
| Knowledge base search   | Semantic            | Understands user intent and question.     |
| News or article search  | Semantic            | Finds related topics and concepts.        |
| FAQ search              | Semantic            | Handles natural language questions.       |

## Basic GraphQL queries

### Run a basic text search

Search across all content types by matching a query term.

```graphql
query SearchContent($query: String!) {
  Content(
    where: { _fulltext: { match: $query } }
    orderBy: { _ranking: RELEVANCE }
  ) {
    items {
      Name
      RelativePath
      _score
    }
    total
  }
}
```

### Variables

```javascript
{ "query": "sustainability" }
```

### Sort results by relevance

Relevance ranking uses traditional keyword-based algorithms.

```graphql
query SearchByRelevance($query: String!) {
  ArticlePage(
    where: { _fulltext: { match: $query } }
    orderBy: { _ranking: RELEVANCE }
    limit: 10
  ) {
    items {
      Name
      TeaserText
      RelativePath
      _score
    }
    total
  }
}
```

### Sort results by semantic ranking

Semantic ranking uses AI models to understand meaning and context.

```graphql
query SearchBySemantic($query: String!) {
  ArticlePage(
    where: { _fulltext: { match: $query } }
    orderBy: { _ranking: SEMANTIC }
    limit: 10
  ) {
    items {
      Name
      TeaserText
      RelativePath
      _score
    }
    total
  }
}
```

### Search across multiple fields

Target specific fields while maintaining relevance scoring.

```graphql
query MultiFieldSearch($query: String!) {
  ArticlePage(
    where: {
      _or: [
        { Name: { match: $query } },
        { TeaserText: { match: $query } },
        { MainBody: { match: $query } }
      ]
    }
    orderBy: { _ranking: RELEVANCE }
  ) {
    items {
      Name
      TeaserText
      RelativePath
      _score
    }
    total
  }
}
```

### Filter by content type

Combine search with content type filtering.

```graphql
query SearchArticles($query: String!) {
  Content(
    where: {
      _and: [
        { _fulltext: { match: $query } },
        { _typeName: { eq: "ArticlePage" } }
      ]
    }
    orderBy: { _ranking: SEMANTIC }
    limit: 5
  ) {
    items {
      Name
      RelativePath
      _score
    }
    total
  }
}
```

### Boost specific fields

Increase the relevance of certain fields.

```graphql
query AdvancedSearch($query: String!) {
  ArticlePage(
    where: {
      _or:[
        { Name: { match: $query, boost: 5 } },
        { TeaserText: { match: $query, boost: 3 } },
        { _fulltext: { match: $query } }
      ]
    }
    orderBy: { _ranking: RELEVANCE }
  ) {
    items {
      Name
      TeaserText
      _score
    }
    total
  }
}
```

### Apply date range filters

Restrict results to recently published content.

```graphql
query SearchWithFilters($query: String!, $fromDate: DateTime!) {
  ArticlePage(
    where: {
      _and: [
        { _fulltext: { match: $query } },
        { StartPublish: { gte: $fromDate } }
      ]
    }
    orderBy: { _ranking: SEMANTIC }
    limit: 20
  ) {
    items {
      Name
      TeaserText
      RelativePath
      _score
      StartPublish
    }
    total
  }
}
```

### Use faceted search

Retrieve facet counts for filtering.

```graphql
query FacetedSearch($query: String!) {
  search: Content(
    where: { _fulltext: { match: $query } }
    orderBy: { _ranking: RELEVANCE }
    limit: 10
  ) {
    items {
      Name
      RelativePath
      _score
    }
    total
  }

  typeFacets: Content(
    where: { _fulltext: { match: $query } }
    facet: { _typeName(limit: 10) }
  ) {
    facet {
      _typeName {
        name
        count
      }
    }
  }
}
```

### Paginate search results

Retrieve search results in pages.

```graphql
query PaginatedSearch($query: String!, $skip: Int = 0, $limit: Int = 10) {
  Content(
    where: { _fulltext: { match: $query } }
    orderBy: { _ranking: SEMANTIC }
    skip: $skip
    limit: $limit
  ) {
    items {
      Name
      RelativePath
      _score
    }
    total
  }
}
```

## References

### Search scores

The `_score` field indicates the relevance of a search result.

- Higher scores mean higher relevance.
- Scores vary depending on the ranking type.
- Filter results based on a minimum `_score`.

```javascript
const { data } = useQuery(SEARCH_QUERY, {
  variables: { query: searchTerm }
});

const relevantResults = data.Content.items.filter(item => item._score > 0.5);
```

## C# implementation

```csharp
public async Task<SearchResult> SearchContentAsync(string query, SearchType searchType = SearchType.Semantic)
{
    var orderBy = searchType == SearchType.Semantic ? "SEMANTIC" : "RELEVANCE";
    
    var graphQLQuery = $@"
        query SearchContent($query: String!) {{
            Content(
                where: {{ _fulltext: {{ match: $query }} }}
                orderBy: {{ _ranking: {orderBy} }}
                limit: 20
            ) {{
                items {{
                    Name
                    RelativePath
                    _score
                }}
                total
            }}
        }}";

    var request = new GraphQLRequest 
    { 
        Query = graphQLQuery,
        Variables = new { query }
    };

    var response = await _graphQLClient.SendQueryAsync<SearchResponse>(request);
    return response.Data;
}

public enum SearchType
{
    Relevance,
    Semantic
}
```
