protected override void Warm(NuGetIndexSearcher searcher) { _logger.LogInformation("NuGetSearcherManager.Warm"); var stopwatch = Stopwatch.StartNew(); // Warmup search (query all documents) searcher.Search(new MatchAllDocsQuery(), 1); // Warmup search (query for a specific term with rankings) var query = NuGetQuery.MakeQuery("newtonsoft.json", searcher.Owners); var boostedQuery = new DownloadsBoostedQuery(query, searcher.DocIdMapping, searcher.Downloads, searcher.Rankings, QueryBoostingContext.Default); searcher.Search(boostedQuery, 5); // Warmup search (with a sort so Lucene field caches are populated) var sort1 = new Sort(new SortField("LastEditedDate", SortField.INT, reverse: true)); var sort2 = new Sort(new SortField("PublishedDate", SortField.INT, reverse: true)); var sort3 = new Sort(new SortField("SortableTitle", SortField.STRING, reverse: false)); var sort4 = new Sort(new SortField("SortableTitle", SortField.STRING, reverse: true)); var topDocs1 = searcher.Search(boostedQuery, null, 250, sort1); var topDocs2 = searcher.Search(boostedQuery, null, 250, sort2); var topDocs3 = searcher.Search(boostedQuery, null, 250, sort3); var topDocs4 = searcher.Search(boostedQuery, null, 250, sort4); // Warmup field caches by fetching data from them using (var writer = new JsonTextWriter(new StreamWriter(new MemoryStream()))) { ResponseFormatter.WriteV2Result(writer, searcher, topDocs1, 0, 250, SemVerHelpers.SemVer2Level); ResponseFormatter.WriteSearchResult(writer, searcher, "http", topDocs1, 0, 250, false, false, SemVerHelpers.SemVer2Level, boostedQuery); ResponseFormatter.WriteV2Result(writer, searcher, topDocs2, 0, 250, SemVerHelpers.SemVer2Level); ResponseFormatter.WriteSearchResult(writer, searcher, "http", topDocs2, 0, 250, false, false, SemVerHelpers.SemVer2Level, boostedQuery); ResponseFormatter.WriteV2Result(writer, searcher, topDocs3, 0, 250, SemVerHelpers.SemVer2Level); ResponseFormatter.WriteSearchResult(writer, searcher, "http", topDocs3, 0, 250, false, false, SemVerHelpers.SemVer2Level, boostedQuery); ResponseFormatter.WriteV2Result(writer, searcher, topDocs4, 0, 250, SemVerHelpers.SemVer2Level); ResponseFormatter.WriteSearchResult(writer, searcher, "http", topDocs4, 0, 250, false, false, SemVerHelpers.SemVer2Level, boostedQuery); } // Done, we're warm. stopwatch.Stop(); _logger.LogInformation("NuGetSearcherManager.Warm: completed in {IndexSearcherWarmDuration} seconds.", stopwatch.Elapsed.TotalSeconds); }
private static Query MakeAutoCompleteQuery(string q, IReadOnlyDictionary <string, int[]> docIdMapping, Downloads downloads, RankingResult rankings, QueryBoostingContext context) { var query = NuGetQuery.MakeAutoCompleteQuery(q); var boostedQuery = new DownloadsBoostedQuery(query, docIdMapping, downloads, rankings, context, 2.0); return(boostedQuery); }
public IDictionary <string, long> Rank(string queryString, IEnumerable <IPackageSearchMetadata> entries) { using (var directory = new RAMDirectory()) { AddToIndex(directory, entries); var searcher = new IndexSearcher(directory); var query = NuGetQuery.MakeQuery(queryString); var topDocs = searcher.Search(query, entries.Count()); var ranking = topDocs.ScoreDocs .Select(d => searcher.Doc(d.Doc)) .Zip(Enumerable.Range(0, topDocs.ScoreDocs.Length).Reverse(), (doc, rank) => new { doc, rank }) .ToDictionary(x => x.doc.Get("Id"), x => (long)x.rank); return(ranking); } }
private static Query MakeSearchQuery(string q, NuGetIndexSearcher searcher) { try { Query query = NuGetQuery.MakeQuery(q, searcher.Owners); Query boostedQuery = new DownloadsBoostedQuery(query, searcher.DocIdMapping, searcher.Downloads, searcher.Rankings, searcher.QueryBoostingContext); return(boostedQuery); } catch (ParseException) { throw new ClientException(HttpStatusCode.BadRequest, "Invalid query format"); } }
public static void Search(JsonWriter jsonWriter, NuGetSearcherManager searcherManager, string q, bool countOnly, bool includePrerelease, NuGetVersion semVerLevel, string sortBy, int skip, int take, string feed, bool ignoreFilter, bool luceneQuery) { if (jsonWriter == null) { throw new ArgumentNullException(nameof(jsonWriter)); } if (searcherManager == null) { throw new ArgumentNullException(nameof(searcherManager)); } var searcher = searcherManager.Get(); try { // The old V2 search service would treat "id:" queries (~match) in the same way as it did "packageid:" (==match). // If "id:" is in the query, replace it. if (luceneQuery && !string.IsNullOrEmpty(q) && q.StartsWith("id:", StringComparison.OrdinalIgnoreCase)) { q = "packageid:" + q.Substring(3); } // Build the query Query query = NuGetQuery.MakeQuery(q, searcher.Owners); // Build filter bool includeUnlisted = ignoreFilter; includePrerelease = ignoreFilter || includePrerelease; feed = ignoreFilter ? null : feed; var combinedQuery = new BooleanQuery(); combinedQuery.Add(query, Occur.SHOULD); // Add this clause to the query here so we still respect semVerLevel that is passed when ignoring filters. if (!SemVerHelpers.ShouldIncludeSemVer2Results(semVerLevel)) { combinedQuery.Add( NuGetQuery.ConstructClauseQuery( new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30), MetadataConstants.LuceneMetadata.SemVerLevelPropertyName, new List <string> { SemVerHelpers.SemVerLevelKeySemVer2 }), Occur.MUST_NOT); } query = combinedQuery; Filter filter = null; if (!ignoreFilter && searcher.TryGetFilter(includeUnlisted, includePrerelease, semVerLevel, feed, out filter)) { // Filter before running the query (make the search set smaller) query = new FilteredQuery(query, filter); } if (countOnly) { DocumentCountImpl(jsonWriter, searcher, query); } else { ListDocumentsImpl(jsonWriter, searcher, query, sortBy, skip, take, semVerLevel); } } finally { searcherManager.Release(searcher); } }