public async Task AggregateAsync_MergesVersions() { var indexer = new RelevanceSearchResultsIndexer(); var aggregator = new SearchResultsAggregator(indexer, new PackageSearchMetadataSplicer()); var queryString = "nuget"; var rawSearch1 = TestUtility.LoadTestResponse("mergeVersions1.json"); var package1 = FindNuGetCorePackage(rawSearch1); var v1 = await GetPackageVersionsAsync(package1); Assert.NotEmpty(v1); var rawSearch2 = TestUtility.LoadTestResponse("mergeVersions2.json"); var package2 = FindNuGetCorePackage(rawSearch2); var v2 = await GetPackageVersionsAsync(package2); Assert.NotEmpty(v2); var results = await aggregator.AggregateAsync(queryString, rawSearch1, rawSearch2); var mergedPackage = FindNuGetCorePackage(results); var vm = await GetPackageVersionsAsync(mergedPackage); Assert.Superset(v1, vm); Assert.Superset(v2, vm); }
public void ProcessUnrankedEntries_FillsWithDefaultRank() { var entries = TestUtility.LoadTestResponse("unrankedEntries.json"); var ranking = new Dictionary <string, long>(StringComparer.OrdinalIgnoreCase) { ["Package1"] = 9, ["Package2"] = 2, ["Package5"] = 3 }; var expected = new Dictionary <string, long> { ["Package1"] = 9, ["Package2"] = 2, ["Package3"] = 3, ["Package4"] = 3, ["Package5"] = 3, ["Package6"] = -1, ["Package7"] = -1, ["Package8"] = -1, ["Package9"] = -1 }; var indexer = new RelevanceSearchResultsIndexer(); var processed = indexer.ProcessUnrankedEntries(entries, ranking); Assert.Equal(expected.OrderBy(x => x.Key), ranking.OrderBy(y => y.Key)); }
private async Task <SearchResult <IPackageSearchMetadata> > AggregateSearchResultsAsync( string searchText, IEnumerable <SearchResult <IPackageSearchMetadata> > results, TelemetryState telemetryState) { SearchResult <IPackageSearchMetadata> result; var nonEmptyResults = results.Where(r => r.Any()).ToArray(); if (nonEmptyResults.Length == 0) { result = SearchResult.Empty <IPackageSearchMetadata>(); } else if (nonEmptyResults.Length == 1) { result = SearchResult.FromItems(nonEmptyResults[0].Items); } else { var items = nonEmptyResults.Select(r => r.Items).ToArray(); var indexer = new RelevanceSearchResultsIndexer(); var aggregator = new SearchResultsAggregator(indexer, new PackageSearchMetadataSplicer()); var aggregatedItems = await aggregator.AggregateAsync( searchText, items); result = SearchResult.FromItems(aggregatedItems.ToArray()); // set correct count of unmerged items result.RawItemsCount = items.Aggregate(0, (r, next) => r + next.Count); } result.SourceSearchStatus = results .SelectMany(r => r.SourceSearchStatus) .ToDictionary(kv => kv.Key, kv => kv.Value); var cursors = results .Where(r => r.NextToken != null) .ToDictionary(r => r.SourceSearchStatus.Single().Key, r => r.NextToken); if (cursors.Keys.Any()) { result.NextToken = new AggregatedContinuationToken { TelemetryState = telemetryState, SearchString = searchText, SourceSearchCursors = cursors }; } return(result); }
private async Task<SearchResult<IPackageSearchMetadata>> AggregateSearchResultsAsync( string searchText, IEnumerable<SearchResult<IPackageSearchMetadata>> results) { SearchResult<IPackageSearchMetadata> result; var nonEmptyResults = results.Where(Enumerable.Any).ToArray(); if (nonEmptyResults.Length == 0) { result = SearchResult.Empty<IPackageSearchMetadata>(); } else if (nonEmptyResults.Length == 1) { result = SearchResult.FromItems(nonEmptyResults[0].Items); } else { var items = nonEmptyResults.Select(r => r.Items).ToArray(); var indexer = new RelevanceSearchResultsIndexer(); var aggregator = new SearchResultsAggregator(indexer, new PackageSearchMetadataSplicer()); var aggregatedItems = await aggregator.AggregateAsync( searchText, items); result = SearchResult.FromItems(aggregatedItems.ToArray()); // set correct count of unmerged items result.RawItemsCount = items.Aggregate(0, (r, next) => r + next.Count); } result.SourceSearchStatus = results .SelectMany(r => r.SourceSearchStatus) .ToDictionary(kv => kv.Key, kv => kv.Value); var cursors = results .Where(r => r.NextToken != null) .ToDictionary(r => r.SourceSearchStatus.Single().Key, r => r.NextToken); if (cursors.Keys.Any()) { result.NextToken = new AggregatedContinuationToken { SearchString = searchText, SourceSearchCursors = cursors }; } return result; }