Website search example 2
Here’s an example of search in a custom data type, including faceted search and search results sorting:
public class ProductSearchQuery { public ProductSearchQuery(CultureInfo culture, string text) { Culture = culture; Text = text; } public CultureInfo Culture { get; } public string Text { get; } public int PageSize { get; set; } = 50; public int PageNumber { get; set; } = 0; public ICollection<string> SelectedTags { get; set; } = new string[0]; public ProductSortByField SortBy { get; set; } public bool SortDescending { get; set; } } public enum ProductSortByField { None = 0, Label = 1, } public class ProductSearchResult { public ICollection<ProductSearchResultEntry> Products { get; set; } public int TotalDocumentsFound { get; set; } public KeyValuePair<string, int>[] TagFacets { get; set; } } public class ProductSearchResultEntry { public string Label { get; set; } public string Description { get; set; } public string Tags { get; set; } public string Url { get; set; } } public class ProductSearch { private readonly ISearchProvider _searchProvider; public ProductSearch(ISearchProvider searchProvider) { _searchProvider = searchProvider ?? throw new ArgumentNullException(nameof(searchProvider)); } public async Task<ProductSearchResult> SearchAsync(ProductSearchQuery query) { var searchQuery = new SearchQuery(query.Text, query.Culture) { MaxDocumentsNumber = query.PageSize, SearchResultOffset = query.PageNumber * query.PageSize }; searchQuery.ShowOnlyDocumentsWithUrls(); searchQuery.FilterByDataTypes(typeof(Product)); // Adding the "product.tags" field to the search query so the facet is returned // as a part of the search results and filtering by the selected tags searchQuery.AddFieldFacet(ProductSearchDocumentSource.TagsFieldName, query.SelectedTags?.ToArray(), null); // Sorting the search results searchQuery.SortOptions = GetSortOptions(query.SortBy, query.SortDescending); var result = await _searchProvider.SearchAsync(searchQuery); return new ProductSearchResult { Products = result.Documents.Select(ToSearchResultEntry).ToList(), TotalDocumentsFound = result.TotalHits, TagFacets = GetSelectedTags(result) }; } private KeyValuePair<string, int>[] GetSelectedTags(Composite.Search.SearchResult result) { var facet = result.Facets?.FirstOrDefault(kvp => kvp.Key == ProductSearchDocumentSource.TagsFieldName); return facet?.Value.Select(f => new KeyValuePair<string, int>(f.Value, f.HitCount)).ToArray(); } private SearchQuerySortOption[] GetSortOptions(ProductSortByField field, bool reverseOrder) { if (field == ProductSortByField.None) return null; if (field == ProductSortByField.Label) { return new [] { new SearchQuerySortOption(DefaultDocumentFieldNames.Label, reverseOrder) }; } throw new InvalidOperationException("Not supported product sort field " + field); } private ProductSearchResultEntry ToSearchResultEntry(SearchDocument doc) { object tags, desc; doc.FieldValues.TryGetValue(DefaultDocumentFieldNames.Description, out desc); doc.FieldValues.TryGetValue(_tagsDocumentField.Name, out tags); return new ProductSearchResultEntry { Label = doc.Label, Description = desc as string, Tags = (string) tags, Url = doc.Url }; } }
Result example: