protected static SearchFilter GetSearchFilter(bool allVersionsInIndex, string url, string searchTerm, bool includePrerelease) { if (url == null) { return(SearchFilter.Empty()); } int indexOfQuestionMark = url.IndexOf('?'); if (indexOfQuestionMark == -1) { return(SearchFilter.Empty()); } string path = url.Substring(0, indexOfQuestionMark); string query = url.Substring(indexOfQuestionMark + 1); if (string.IsNullOrEmpty(query)) { return(SearchFilter.Empty()); } var searchFilter = new SearchFilter() { // The way the default paging works is WCF attempts to read up to the MaxPageSize elements. If it finds as many, it'll assume there // are more elements to be paged and generate a continuation link. Consequently we'll always ask to pull MaxPageSize elements so WCF generates the // link for us and then allow it to do a Take on the results. Further down, we'll also parse $skiptoken as a custom IDataServicePagingProvider // sneakily injects the Skip value in the continuation token. Take = MaxPageSize, Skip = 0, CountOnly = path.EndsWith("$count", StringComparison.Ordinal), IsValid = true, SearchTerm = searchTerm, IncludePrerelease = includePrerelease, }; string[] props = query.Split('&'); IDictionary <string, string> queryTerms = new Dictionary <string, string>(); foreach (string prop in props) { string[] nameValue = prop.Split('='); if (nameValue.Length == 2) { queryTerms[nameValue[0]] = nameValue[1]; } } searchFilter.QueryTerms = queryTerms; string filter; if (queryTerms.TryGetValue("$filter", out filter)) { if (!(filter.Equals("IsLatestVersion", StringComparison.Ordinal) || filter.Equals("IsAbsoluteLatestVersion", StringComparison.Ordinal) || filter.Contains("IsLatestVersion") || filter.Contains("IsAbsoluteLatestVersion"))) { searchFilter.IncludeAllVersions = true; } } else { searchFilter.IncludeAllVersions = true; } // We'll only use the index if we the query searches for latest \ latest-stable packages // if all versions are not available in the index if (searchFilter.IncludeAllVersions && !allVersionsInIndex) { searchFilter.IsValid = false; searchFilter.FilterInvalidReason = SearchFilterInvalidReason.DueToAllVersionsRequested; } string skipStr; if (queryTerms.TryGetValue("$skip", out skipStr)) { int skip; if (int.TryParse(skipStr, out skip)) { searchFilter.Skip = skip; } } string topStr; if (queryTerms.TryGetValue("$top", out topStr)) { int top; if (int.TryParse(topStr, out top)) { searchFilter.Take = Math.Min(top, MaxPageSize); } } string skipTokenStr; if (queryTerms.TryGetValue("$skiptoken", out skipTokenStr)) { var skipTokenParts = skipTokenStr.Split(','); if (skipTokenParts.Length == 3) // this means our custom IDataServicePagingProvider did its magic by sneaking the Skip value into the SkipToken { int skip; if (int.TryParse(skipTokenParts[2], out skip)) { searchFilter.Skip = skip; } } } // only certain orderBy clauses are supported from the Lucene search string orderBy; if (queryTerms.TryGetValue("$orderby", out orderBy)) { if (string.IsNullOrEmpty(orderBy)) { searchFilter.SortProperty = SortProperty.Relevance; } else if (orderBy.StartsWith("DownloadCount", StringComparison.Ordinal)) { searchFilter.SortProperty = SortProperty.DownloadCount; } else if (orderBy.StartsWith("Published", StringComparison.Ordinal)) { searchFilter.SortProperty = SortProperty.Recent; } else if (orderBy.StartsWith("LastEdited", StringComparison.Ordinal)) { searchFilter.SortProperty = SortProperty.Recent; } else if (orderBy.StartsWith("Id", StringComparison.Ordinal)) { searchFilter.SortProperty = SortProperty.DisplayName; } else if (orderBy.StartsWith("concat", StringComparison.Ordinal)) { searchFilter.SortProperty = SortProperty.DisplayName; if (orderBy.Contains("%20desc")) { searchFilter.SortDirection = SortDirection.Descending; } } else { searchFilter.IsValid = false; } } else { searchFilter.SortProperty = SortProperty.Relevance; } return(searchFilter); }
public IQueryable <V2FeedPackage> Search(string searchTerm, string targetFramework, bool includePrerelease) { var packages = PackageRepo.GetAll().Where(p => p.StatusForDatabase == PackageStatusType.Submitted.GetDescriptionOrValue()); var packageVersions = SearchCore(packages, searchTerm, targetFramework, includePrerelease, SearchFilter.Empty()).ToV2FeedPackageQuery(GetSiteRoot()).ToList(); if (!includePrerelease) { return(packageVersions.Where(p => !p.IsPrerelease).AsQueryable()); } return(packageVersions.AsQueryable()); }