private IFieldSort SortFromUserInput(FieldSortDescriptor <BusinessElasticModel> f, BusinessSorting sorting) { switch (sorting) { case BusinessSorting.HeaderDesc: f.Order(SortOrder.Descending); f.Field(ff => ff.Header.Suffix("keyword")); break; case BusinessSorting.HeaderAcs: f.Order(SortOrder.Ascending); f.Field(ff => ff.Header.Suffix("keyword")); break; case BusinessSorting.LatestAdded: f.Order(SortOrder.Descending); f.Field(ff => ff.Created); break; case BusinessSorting.LatestUpdated: f.Order(SortOrder.Descending); f.Field(ff => ff.LastUpdated); break; default: f.Field("_score"); f.Descending(); break; } return(f); }
public async Task <BusinessElasticReturnModel> GetBusinesses( long randomSeed, int from = 0, int size = 10, string query = null, string tags = null, string transactionTags = null, int[] regionIds = null, bool?digital = null, bool openNow = false, BusinessSorting sorting = BusinessSorting.Random, string languageCode = CmsVariable.DefaultLanguageCode) { var stopwatch = new Stopwatch(); stopwatch.Start(); ISearchResponse <BusinessElasticModel> response; Func <AggregationContainerDescriptor <BusinessElasticModel>, IAggregationContainer> aggregation = a => a.Terms("by_tags", f => f.Field(c => c.Tags.Suffix("keyword")).Size(1000)); if (sorting == BusinessSorting.Random) { response = await _client.SearchAsync <BusinessElasticModel>(s => s .RequestConfiguration(r => r.DisableDirectStreaming()) .From(from) .Size(size) .Aggregations(aggregation) .Query(oq => oq.FunctionScore(fs => fs .Query(MainQuery(query, tags, transactionTags, regionIds, digital, openNow, languageCode)) .Functions(f => f.RandomScore(rs => rs.Seed(randomSeed)))) ) ); } else { response = await _client.SearchAsync <BusinessElasticModel>(s => s .RequestConfiguration(r => r.DisableDirectStreaming()) .From(from) .Size(size) .Aggregations(aggregation) .Query(MainQuery(query, tags, transactionTags, regionIds, digital, openNow, languageCode)) .Sort(ss => ss.Field(f => SortFromUserInput(f, sorting))) ); } stopwatch.Stop(); if (!response.IsValid) { var errorMessage = $"Response invalid when searching businesses in Elasticsearch."; _logger.LogError(errorMessage + " {Debug}", response.DebugInformation); throw new Exception(errorMessage); } var logMessage = $"Query:{query}, regionIds:{regionIds}, LanguageCode:{languageCode}, tags:{tags}, digital:{digital}"; _logger.LogInformation("Search businesses with filter {LogMessage} found {Count} items. Took {ElapsedTime} milliseconds.", logMessage, response.Documents?.Count, stopwatch?.Elapsed.TotalMilliseconds); var list = response.Hits.Select(x => new BusinessElasticReturnItemModel { Business = x.Source, Score = x.Score }); var byTags = response.Aggregations.Terms("by_tags").Buckets.Select(x => new BusinessElasticTagBucketModel { Key = x.Key, DocCount = x.DocCount ?? 0 }).ToList(); return(new BusinessElasticReturnModel { Items = list.ToList(), Total = response.Total, TagCounts = byTags }); }