private static Query ParseQuery(string searchTerm) { var fields = new Dictionary<string, float> { { "Id", 1.2f }, { "Title", 1.0f }, { "Tags", 0.8f }, { "Description", 0.1f }, { "Author", 1.0f } }; var analyzer = new StandardAnalyzer(LuceneCommon.LuceneVersion); var queryParser = new MultiFieldQueryParser(LuceneCommon.LuceneVersion, fields.Keys.ToArray(), analyzer, fields); var conjuctionQuery = new BooleanQuery(); conjuctionQuery.SetBoost(2.0f); var disjunctionQuery = new BooleanQuery(); disjunctionQuery.SetBoost(0.1f); var wildCardQuery = new BooleanQuery(); wildCardQuery.SetBoost(0.5f); // Escape the entire term we use for exact searches. var escapedSearchTerm = Escape(searchTerm); var exactIdQuery = new TermQuery(new Term("Id-Exact", escapedSearchTerm)); exactIdQuery.SetBoost(2.5f); var wildCardIdQuery = new WildcardQuery(new Term("Id-Exact", "*" + escapedSearchTerm + "*")); foreach(var term in GetSearchTerms(searchTerm)) { var termQuery = queryParser.Parse(term); conjuctionQuery.Add(termQuery, BooleanClause.Occur.MUST); disjunctionQuery.Add(termQuery, BooleanClause.Occur.SHOULD); foreach (var field in fields) { var wildCardTermQuery = new WildcardQuery(new Term(field.Key, term + "*")); wildCardTermQuery.SetBoost(0.7f * field.Value); wildCardQuery.Add(wildCardTermQuery, BooleanClause.Occur.SHOULD); } } var downloadCountBooster = new FieldScoreQuery("DownloadCount", FieldScoreQuery.Type.INT); return new CustomScoreQuery(conjuctionQuery.Combine(new Query[] { exactIdQuery, wildCardIdQuery, conjuctionQuery, disjunctionQuery, wildCardQuery }), downloadCountBooster); }
private static Query BuildGeneralQuery( bool doExactId, string originalSearchText, Analyzer analyzer, IEnumerable<NuGetSearchTerm> generalTerms, IEnumerable<Query> generalQueries) { // All terms in the multi-term query appear in at least one of the target fields. var conjuctionQuery = new BooleanQuery(); conjuctionQuery.SetBoost(2.0f); // Some terms in the multi-term query appear in at least one of the target fields. var disjunctionQuery = new BooleanQuery(); disjunctionQuery.SetBoost(0.1f); // Suffix wildcard search e.g. jquer* var wildCardQuery = new BooleanQuery(); wildCardQuery.SetBoost(0.5f); string escapedExactId = originalSearchText.ToLowerInvariant(); Query exactIdQuery = null; Query wildCardIdQuery = null; if (doExactId) { exactIdQuery = new TermQuery(new Term("Id-Exact", escapedExactId)); exactIdQuery.SetBoost(7.5f); wildCardIdQuery = new WildcardQuery(new Term("Id-Exact", "*" + escapedExactId + "*")); } Query nearlyExactIdQuery = null; if (generalTerms.Any()) { string escapedApproximateId = string.Join(" ", generalTerms.Select(c => c.TermOrPhrase)); nearlyExactIdQuery = AnalysisHelper.GetFieldQuery(analyzer, "Id", escapedApproximateId); nearlyExactIdQuery.SetBoost(2.0f); } foreach (var termQuery in generalQueries) { conjuctionQuery.Add(termQuery, BooleanClause.Occur.MUST); disjunctionQuery.Add(termQuery, BooleanClause.Occur.SHOULD); } var sanitizedTerms = generalTerms.Select(c => c.TermOrPhrase.ToLowerInvariant()); foreach (var sanitizedTerm in sanitizedTerms) { foreach (var field in Fields) { var wildCardTermQuery = new WildcardQuery(new Term(field, sanitizedTerm + "*")); wildCardTermQuery.SetBoost(0.7f); wildCardQuery.Add(wildCardTermQuery, BooleanClause.Occur.SHOULD); } } // OR of all the applicable queries var queries = new Query[] { exactIdQuery, wildCardIdQuery, nearlyExactIdQuery, conjuctionQuery, disjunctionQuery, wildCardQuery }; var queriesToCombine = queries.Where(q => !IsDegenerateQuery(q)); var query = conjuctionQuery.Combine(queriesToCombine.ToArray()); return query; }
private static Query ParseQuery(SearchFilter searchFilter) { var fields = new[] { "Id", "Title", "Tags", "Description", "Author" }; var analyzer = new StandardAnalyzer(LuceneCommon.LuceneVersion); var queryParser = new MultiFieldQueryParser(LuceneCommon.LuceneVersion, fields, analyzer); // All terms in the multi-term query appear in at least one of the fields. var conjuctionQuery = new BooleanQuery(); conjuctionQuery.SetBoost(2.0f); // Some terms in the multi-term query appear in at least one of the fields. var disjunctionQuery = new BooleanQuery(); disjunctionQuery.SetBoost(0.1f); // Suffix wildcard search e.g. jquer* var wildCardQuery = new BooleanQuery(); wildCardQuery.SetBoost(0.5f); // Escape the entire term we use for exact searches. var escapedSearchTerm = Escape(searchFilter.SearchTerm); var exactIdQuery = new TermQuery(new Term("Id-Exact", escapedSearchTerm)); exactIdQuery.SetBoost(2.5f); var wildCardIdQuery = new WildcardQuery(new Term("Id-Exact", "*" + escapedSearchTerm + "*")); foreach (var term in GetSearchTerms(searchFilter.SearchTerm)) { var termQuery = queryParser.Parse(term); conjuctionQuery.Add(termQuery, BooleanClause.Occur.MUST); disjunctionQuery.Add(termQuery, BooleanClause.Occur.SHOULD); foreach (var field in fields) { var wildCardTermQuery = new WildcardQuery(new Term(field, term + "*")); wildCardTermQuery.SetBoost(0.7f); wildCardQuery.Add(wildCardTermQuery, BooleanClause.Occur.SHOULD); } } // Create an OR of all the queries that we have var combinedQuery = conjuctionQuery.Combine(new Query[] { exactIdQuery, wildCardIdQuery, conjuctionQuery, disjunctionQuery, wildCardQuery }); if (searchFilter.SortProperty == SortProperty.Relevance) { // If searching by relevance, boost scores by download count. var downloadCountBooster = new FieldScoreQuery("DownloadCount", FieldScoreQuery.Type.INT); return new CustomScoreQuery(combinedQuery, downloadCountBooster); } return combinedQuery; }
private static Query ParseQuery(string searchTerm) { var fields = new Dictionary<string, float> { { "Id", 1.2f }, { "Title", 1.0f }, { "Tags", 1.0f}, { "Description", 0.8f }, { "Author", 0.6f } }; var analyzer = new StandardAnalyzer(LuceneCommon.LuceneVersion); searchTerm = QueryParser.Escape(searchTerm).ToLowerInvariant(); var queryParser = new MultiFieldQueryParser(LuceneCommon.LuceneVersion, fields.Keys.ToArray(), analyzer, fields); var conjuctionQuery = new BooleanQuery(); conjuctionQuery.SetBoost(1.5f); var disjunctionQuery = new BooleanQuery(); var wildCardQuery = new BooleanQuery(); wildCardQuery.SetBoost(0.7f); var exactIdQuery = new TermQuery(new Term("Id-Exact", searchTerm)); exactIdQuery.SetBoost(2.5f); foreach(var term in searchTerm.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)) { conjuctionQuery.Add(queryParser.Parse(term), BooleanClause.Occur.MUST); disjunctionQuery.Add(queryParser.Parse(term), BooleanClause.Occur.SHOULD); foreach (var field in fields) { var wildCardTermQuery = new WildcardQuery(new Term(field.Key, term + "*")); wildCardTermQuery.SetBoost(0.7f * field.Value); wildCardQuery.Add(wildCardTermQuery, BooleanClause.Occur.SHOULD); } } return conjuctionQuery.Combine(new Query[] { exactIdQuery, conjuctionQuery, disjunctionQuery, wildCardQuery }); }