private static Query ParseQuery(SearchFilter searchFilter) { if (String.IsNullOrWhiteSpace(searchFilter.SearchTerm)) { return(new MatchAllDocsQuery()); } 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); }
/// <summary> /// Adds a wildcard clause to this instance /// </summary> /// <remarks>Wildcard clauses include '*' and '?' character</remarks> /// <param name="term">Term to add to this query</param> /// <param name="occurrence">Defines how the term is added to this query</param> public void AddWildcardClause(SearchTerm term, ClauseOccurrence occurrence) { if (term == null) { throw new ArgumentNullException("term", "term cannot be null"); } IncrementTotalClauses(1); WildcardQuery wildcardQuery = new WildcardQuery(term.GetLuceneTerm()); wildcardQuery.SetBoost(term.Boost); this.luceneQuery.Add(wildcardQuery, TypeConverter.ConvertToLuceneClauseOccurrence(occurrence)); wildcardQuery = null; }
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 })); }
/// <summary> /// Adds a wildcard clause to this instance /// </summary> /// <remarks>Wildcard clauses include '*' and '?' character</remarks> /// <param name="term">Term to add to this query</param> /// <param name="occurrence">Defines how the term is added to this query</param> public void AddWildcardClause(SearchTerm term, ClauseOccurrence occurrence) { if (term == null) throw new ArgumentNullException("term", "term cannot be null"); IncrementTotalClauses(1); WildcardQuery wildcardQuery = new WildcardQuery(term.GetLuceneTerm()); wildcardQuery.SetBoost(term.Boost); this.luceneQuery.Add(wildcardQuery, TypeConverter.ConvertToLuceneClauseOccurrence(occurrence)); wildcardQuery = null; }
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); }