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:


