Skip to content

Commit 14b383e

Browse files
Merge pull request #3203 from HeidiSteen/heidist-facets
Facet clean up, pass 4
2 parents 451af58 + 3b96c3d commit 14b383e

File tree

1 file changed

+15
-50
lines changed

1 file changed

+15
-50
lines changed

articles/search/search-faceted-navigation.md

Lines changed: 15 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,10 @@ ms.date: 02/26/2025
1313

1414
# Add faceted navigation to a search app
1515

16-
Faceted navigation is used for self-directed drilldown filtering on query results in a search app, where your application offers form controls for scoping search to groups of documents (for example, categories or brands), and Azure AI Search provides the data structures and filters to back the experience.
16+
Faceted navigation is used for self-directed drill-down filtering on query results in a search app, where your application offers form controls for scoping search to groups of documents (for example, categories or brands), and Azure AI Search provides the data structures and filters to back the experience.
1717

1818
In this article, learn how to create a faceted navigation structure in Azure AI Search.
1919

20-
<!-- > [!div class="checklist"]
21-
> * Set field attributes in the index
22-
> * Structure the request and response
23-
> * Add navigation controls and filters in the presentation layer
24-
25-
Code in the presentation layer does the heavy lifting in a faceted navigation experience. The demos and samples listed at the end of this article provide working code that shows you how to bring everything together.
26-
-->
27-
2820
## Faceted navigation in a search page
2921

3022
Facets are dynamic and returned on a query. A search response brings with it all of the facet categories used to navigate the documents in the result. The query executes first, and then facets are pulled from the current results and assembled into a faceted navigation structure.
@@ -39,9 +31,9 @@ Facets can help you find what you're looking for, while ensuring that you don't
3931

4032
Facets are enabled on a field-by-field basis in an index definition when you set the "facetable" attribute to true.
4133

42-
Although it's not strictly required, you should also set the "filterable" attribute so that you can build the necessary filters that back the faceted navigation experience in your search application.
34+
Although it's not strictly required, it's a best practice to also set the "filterable" attribute so that you can build the necessary filters that back the faceted navigation experience in your search application.
4335

44-
The following example of the "hotels" sample index shows "facetable" and "filterable" on low cardinality fields that contain single values or short phrases: "Category", "Tags", "Rating".
36+
The following example of the hotels sample index shows "facetable" and "filterable" on low cardinality fields that contain single values or short phrases: "Category", "Tags", "Rating".
4537

4638
```json
4739
{
@@ -62,28 +54,30 @@ The following example of the "hotels" sample index shows "facetable" and "filter
6254

6355
Facets can be calculated over single-value fields and collections. Fields that work best in faceted navigation have these characteristics:
6456

57+
* Human readable (nonvector) content
58+
6559
* Low cardinality (a small number of distinct values that repeat throughout documents in your search corpus)
6660

6761
* Short descriptive values (one or two words) that render nicely in a navigation tree
6862

6963
The values within a field, and not the field name itself, produce the facets in a faceted navigation structure. If the facet is a string field named *Color*, facets are blue, green, and any other value for that field.
7064

71-
You can't use `Edm.GeographyPoint` or `Collection(Edm.GeographyPoint)` fields in faceted navigation. Facets work best on fields with low cardinality. Due to the resolution of geo-coordinates, it's rare that any two sets of coordinates are equal in a given dataset. As such, facets aren't supported for geo-coordinates. You should use a city or region field to facet by location.
65+
You can't use `Edm.GeographyPoint` or `Collection(Edm.GeographyPoint)` fields in faceted navigation. Recall that facets work best on fields with low cardinality. Due to the resolution of geo-coordinates, it's rare that any two sets of coordinates are equal in a given dataset. As such, facets aren't supported for geo-coordinates. You should use a city or region field to facet by location.
7266

73-
> [!TIP]
74-
> As a best practice for performance and storage optimization, turn faceting off for fields that should never be used as a facet. In particular, string fields for unique values, such as an ID or product name, should be set to `"facetable": false` to prevent their accidental (and ineffective) use in faceted navigation. This is especially true for the REST API that enables filters and facets by default.
67+
As a best practice for performance and storage optimization, turn faceting off for fields that should never be used as a facet. In particular, string fields for unique values, such as an ID or product name, should be set to `"facetable": false` to prevent their accidental (and ineffective) use in faceted navigation. This is especially true for the REST API that enables filters and facets on string fields by default.
7568

76-
As a best practice, check fields for null values, misspellings or case discrepancies, and single and plural versions of the same word. By default, filters and facets don't undergo lexical analysis or [spell check](speller-how-to-add.md), which means that all values of a "facetable" field are potential facets, even if the words differ by one character. Optionally, you can [assign a normalizer](search-normalizers.md) to a "filterable" and "facetable" field to smooth out variations in casing and characters.
69+
In your code, check fields for null values, misspellings or case discrepancies, and single and plural versions of the same word. By default, filters and facets don't undergo lexical analysis or [spell check](speller-how-to-add.md), which means that all values of a "facetable" field are potential facets, even if the words differ by one character. Optionally, you can [assign a normalizer](search-normalizers.md) to a "filterable" and "facetable" field to smooth out variations in casing and characters.
7770

7871
### Defaults in REST and Azure SDKs
7972

80-
If you're using one of the Azure SDKs, your code must explicitly set the field attributes. In contrast, the REST API has defaults for field attributes based on the [data type](/rest/api/searchservice/supported-data-types). The following data types are "filterable" and "facetable" by default:
73+
If you're using one of the Azure SDKs, your code must explicitly set the "facetable" attribute on a field.
74+
75+
The REST API has defaults for field attributes based on the [data type](/rest/api/searchservice/supported-data-types). The following data types are "filterable" and "facetable" by default:
8176

82-
* `Edm.String`
83-
* `Edm.DateTimeOffset`
84-
* `Edm.Boolean`
85-
* `Edm.Int32`, `Edm.Int64`, `Edm.Double`
86-
* Collections of any of the above types, for example `Collection(Edm.String)` or `Collection(Edm.Double)`
77+
* `Edm.String` and `Collection(Edm.String)`
78+
* `Edm.DateTimeOffset` and `Collection(Edm.DateTimeOffset)`
79+
* `Edm.Boolean` and`Collection(Edm.Boolean)`
80+
* `Edm.Int32`, `Edm.Int64`, `Edm.Double` and their collection equivalents
8781

8882
## Facet request and response
8983

@@ -207,35 +201,6 @@ if (!String.IsNullOrEmpty(categoryFacet))
207201
filter = $"category eq '{categoryFacet}'";
208202
```
209203
210-
### HTML for faceted navigation
211-
212-
The following example, taken from the `index.cshtml` file of the NYCJobs sample application, shows the static HTML structure for displaying faceted navigation on the search results page. The list of facets is built or rebuilt dynamically when you submit a search term, or select or clear a facet.
213-
214-
```html
215-
<div class="widget sidebar-widget jobs-filter-widget">
216-
<h5 class="widget-title">Filter Results</h5>
217-
<p id="filterReset"></p>
218-
<div class="widget-content">
219-
220-
<h6 id="businessTitleFacetTitle">Business Title</h6>
221-
<ul class="filter-list" id="business_title_facets">
222-
</ul>
223-
224-
<h6>Location</h6>
225-
<ul class="filter-list" id="posting_type_facets">
226-
</ul>
227-
228-
<h6>Posting Type</h6>
229-
<ul class="filter-list" id="posting_type_facets"></ul>
230-
231-
<h6>Minimum Salary</h6>
232-
<ul class="filter-list" id="salary_range_facets">
233-
</ul>
234-
235-
</div>
236-
</div>
237-
```
238-
239204
### Build HTML dynamically
240205
241206
The following code snippet from the `index.cshtml` (also from NYCJobs demo) dynamically builds the HTML to display the first facet, Business Title. Similar functions dynamically build the HTML for the other facets. Each facet has a label and a count, which displays the number of items found for that facet result.

0 commit comments

Comments
 (0)