private static IQueryable<Package> FormatResults(SearchFilter searchFilter, SearchResults result) { // For count queries, we can ask the SearchService to not filter the source results. This would avoid hitting the database and consequently make it very fast. if (searchFilter.CountOnly) { // At this point, we already know what the total count is. We can have it return this value very quickly without doing any SQL. return result.Data.InterceptWith(new CountInterceptor(result.Hits)); } // For relevance search, Lucene returns us a paged/sorted list. OData tries to apply default ordering and Take / Skip on top of this. // It also tries to filter to latest versions, but the search service already did that! // We avoid it by yanking these expressions out of out the tree. return result.Data .InterceptWith(new CountInterceptor(result.Hits)) .InterceptWith(new DisregardODataInterceptor()); }
private async Task<SearchResults> SearchCore(SearchFilter filter, bool raw) { // Query! var sw = new Stopwatch(); sw.Start(); var result = await _client.Search( filter.SearchTerm, projectTypeFilter: null, includePrerelease: filter.IncludePrerelease, curatedFeed: filter.CuratedFeed == null ? null : filter.CuratedFeed.Name, sortBy: filter.SortOrder, skip: filter.Skip, take: filter.Take, isLuceneQuery: raw, countOnly: filter.CountOnly, explain: false, getAllVersions: filter.IncludeAllVersions, supportedFramework: filter.SupportedFramework); sw.Stop(); SearchResults results = null; if (result.IsSuccessStatusCode) { var content = await result.ReadContent(); if (filter.CountOnly || content.TotalHits == 0) { results = new SearchResults(content.TotalHits, content.IndexTimestamp); } else { results = new SearchResults( content.TotalHits, content.IndexTimestamp, content.Data.Select(ReadPackage).AsQueryable()); } } Trace.PerfEvent( SearchRoundtripTimePerfCounter, sw.Elapsed, new Dictionary<string, object>() { {"Term", filter.SearchTerm}, {"Context", filter.Context}, {"Raw", raw}, {"Hits", results == null ? -1 : results.Hits}, {"StatusCode", (int)result.StatusCode}, {"SortOrder", filter.SortOrder.ToString()}, {"CuratedFeed", filter.CuratedFeed == null ? null : filter.CuratedFeed.Name}, {"Url", TryGetUrl()} }); result.HttpResponse.EnsureSuccessStatusCode(); return results; }