---
title: Integrate search
slug: cms-11/dev-docs/search-integration
docTags: 
createdAt: 2026-07-22T19:45:19.643Z
---

:::hint{type="info"}
**Note**
The Full-text Search Service applies to Optimizely Content Management System (CMS 11) and is not supported on Optimizely Digital Experience Platform (DXP) and other cloud service deployments. It is a legacy feature that will be removed in future versions.

**This section is not supported for ASP.NET Core-based applications.**
:::

CMS stores information about CMS content (pages and blocks) in a searchable index. To find items in the index, compose search queries from different subqueries. The following samples show how you can search in that index.

**How to search for pages**

```csharp
public IEnumerable<PageData> FindPages(string searchQuery, ContentReference searchRoot, string cultureId, int pagingNumber, int pagingSize) {
  // The group query is needed to combine the different criteria
  GroupQuery groupQuery = new GroupQuery(LuceneOperator.AND);

  // The content query makes sure we only get hits that are of the type PageData
  groupQuery.QueryExpressions.Add(new ContentQuery<PageData>());

  // The field query contains the search phrase
  groupQuery.QueryExpressions.Add(new FieldQuery(searchQuery));

  // The virtual path query makes sure that we only get hits for children of the specified search root
  VirtualPathQuery pathQuery = new VirtualPathQuery();
  pathQuery.AddContentNodes(searchRoot);
  groupQuery.QueryExpressions.Add(pathQuery);

  // The access control list query will remove any pages the user doesn't have read access to
  AccessControlListQuery aclQuery = new AccessControlListQuery();
  aclQuery.AddAclForUser(PrincipalInfo.Current, HttpContext.Current);
  groupQuery.QueryExpressions.Add(aclQuery);

  // Add a specific field query for the Culture field in order to search for a specific culture
  groupQuery.QueryExpressions.Add(new FieldQuery(cultureId, Field.Culture));

  var searchHandler = ServiceLocator.Current.GetInstance<SearchHandler>();
  SearchResults results = searchHandler.GetSearchResults(groupQuery, pagingNumber, pagingSize);

  var contentSearchHandler = ServiceLocator.Current.GetInstance<ContentSearchHandler>();
  foreach(var hit in results.IndexResponseItems) {
    // Use the content search handler to convert the page hit into a PageData
    yield
    return contentSearchHandler.GetContent<PageData>(hit);
  }
}
```

**How to search for files**

```csharp
public IEnumerable<string> FindFiles(string searchQuery, VersioningDirectory searchRoot, int pagingNumber, int pagingSize) {
  // The group query is needed to combine the different criteria
  GroupQuery groupQuery = new GroupQuery(LuceneOperator.AND);

  // The unified file query makes sure we only get hits that are files
  groupQuery.QueryExpressions.Add(new UnifiedFileQuery());

  // The field query contains the search phrase
  groupQuery.QueryExpressions.Add(new FieldQuery(searchQuery));

  // The virtual path query makes sure that we only get hits for children of the specified search root
  VirtualPathQuery pathQuery = new VirtualPathQuery();
  pathQuery.AddDirectoryNodes(searchRoot);
  groupQuery.QueryExpressions.Add(pathQuery);

  // The access control list query will remove any files the user doesn't have read access to
  AccessControlListQuery aclQuery = new AccessControlListQuery();
  aclQuery.AddAclForUser(PrincipalInfo.Current, HttpContext.Current);
  groupQuery.QueryExpressions.Add(aclQuery);

  var searchHandler = ServiceLocator.Current.GetInstance<SearchHandler>();
  SearchResults results = searchHandler.GetSearchResults(groupQuery, pagingNumber, pagingSize);

  foreach(var hit in results.IndexResponseItems) {
    // Return the virtual path for each matching file.
    yield
    return hit.Uri.ToString();
  }
}
```

### CMS types are stored in the index

CMS stores types in the index by mapping values from the objects onto an `IndexRequestItem`, and send it to the indexing service. `PageData` and `VersioningFile` are two of the most common indexed CMS types that it stores in the index.

When you store a `PageData` in the index, its properties are mapped to the fields on the index request item in the following way.

| IndexRequestItem item  | PageData page                                                          |                     |
| ---------------------- | ---------------------------------------------------------------------- | ------------------- |
| item.Id                | page.PageGuid                                                          | page.LanguageBranch |
| item.Uri               | page.LinkUrl                                                           |                     |
| item.Title             | page.Name                                                              |                     |
| item.Created           | page.Created                                                           |                     |
| item.Modified          | page.Changed                                                           |                     |
| item.Culture           | page.LanguageBranch                                                    |                     |
| item.ItemType          | A comma-separated list of the type of the page and any inherited types |                     |
| item.Authors           | page.CreatedBy                                                         |                     |
| item.DisplayText       | Content from  searchable properties on the page                        |                     |
| item.AccessControlList | page.ACL, but only about read access                                   |                     |
| item.Categories        | page.Category                                                          |                     |
| item.VirtualPathNodes  | The ancestors to the page, ordered with the oldest first               |                     |
| item.ItemStatus        | Always approved                                                        |                     |
| item.PublicationEnd    | page.StopPublish                                                       |                     |

When you store a `VersioningFile` in the index, its properties are mapped to the fields the following way.

| IndexRequestItem item  | VersioningFile file                                                  |
| ---------------------- | -------------------------------------------------------------------- |
| item.Id                | file.Guid                                                            |
| item.Title             | file.Name                                                            |
| item.DataUri           | file.LocalPath                                                       |
| item.Uri               | file.PermanentLinkVirtualPath or file.VirtualPath                    |
| item.Authors           | file.Summary.Author                                                  |
| item.Categories        | file.Summary.Category split by character ','                         |
| item.ItemStatus        | Always approved                                                      |
| item.Metadata          | file.Name without extension and  values from file.Summary.Dictionary |
| item.AccessControlList | Users and roles with read access from file.Parent.ACL                |
| item.VirtualPathNodes  | The guid of each parent directory ending with file.Guid              |
| item.DisplayText       | The content of the file, if you installed required IFilter           |
