private static Query ParseQuery(SearchFilter searchFilter) { // 1. parse the query into field clauses and general terms // We imagine that mostly, field clauses are meant to 'filter' results found searching for general terms. // The resulting clause collections may be empty. var queryParser = new NuGetQueryParser(); var clauses = queryParser.Parse(searchFilter.SearchTerm).Select(StandardizeSearchTerms).ToList(); var fieldSpecificTerms = clauses.Where(a => a.Field != null); var generalTerms = clauses.Where(a => a.Field == null); // Convert terms to appropriate Lucene Query objects var analyzer = new PerFieldAnalyzer(); var fieldSpecificQueries = fieldSpecificTerms .Select(c => AnalysisHelper.GetFieldQuery(analyzer, c.Field, c.TermOrPhrase)) .Where(q => !IsDegenerateQuery(q)) .ToList(); var generalQueries = generalTerms .Select(c => AnalysisHelper.GetMultiFieldQuery(analyzer, Fields, c.TermOrPhrase)) .Where(q => !IsDegenerateQuery(q)) .ToList(); if (fieldSpecificQueries.Count == 0 && generalQueries.Count == 0) { return(new MatchAllDocsQuery()); } // At this point we try to detect user intent... // a) General search? [foo bar] // b) Id-targeted search? [id:Foo bar] // c) Other Field-targeted search? [author:Foo bar] bool doExactId = !fieldSpecificQueries.Any(); Query generalQuery = BuildGeneralQuery(doExactId, searchFilter.SearchTerm, analyzer, generalTerms, generalQueries); // IF field targeting is done, we should basically want to AND their field specific queries with all other query terms if (fieldSpecificQueries.Any()) { var combinedQuery = new BooleanQuery(); if (!IsDegenerateQuery(generalQuery)) { combinedQuery.Add(generalQuery, Occur.MUST); } foreach (var fieldQuery in fieldSpecificQueries) { if (!IsDegenerateQuery(fieldQuery)) { combinedQuery.Add(fieldQuery, Occur.MUST); } } generalQuery = combinedQuery; } return(generalQuery); }
private static Query ParseQuery(SearchFilter searchFilter) { // 1. parse the query into field clauses and general terms // We imagine that mostly, field clauses are meant to 'filter' results found searching for general terms. // The resulting clause collections may be empty. var queryParser = new NuGetQueryParser(); var clauses = queryParser.Parse(searchFilter.SearchTerm).Select(StandardizeSearchTerms).ToList(); var fieldSpecificTerms = clauses.Where(a => a.Field != null); var generalTerms = clauses.Where(a => a.Field == null); // Convert terms to appropriate Lucene Query objects var analyzer = new PerFieldAnalyzer(); var fieldSpecificQueries = fieldSpecificTerms .Select(c => AnalysisHelper.GetFieldQuery(analyzer, c.Field, c.TermOrPhrase)) .Where(q => !IsDegenerateQuery(q)) .ToList(); var generalQueries = generalTerms .Select(c => AnalysisHelper.GetMultiFieldQuery(analyzer, Fields, c.TermOrPhrase)) .Where(q => !IsDegenerateQuery(q)) .ToList(); if (fieldSpecificQueries.Count == 0 && generalQueries.Count == 0) { return new MatchAllDocsQuery(); } // At this point we try to detect user intent... // a) General search? [foo bar] // b) Id-targeted search? [id:Foo bar] // c) Other Field-targeted search? [author:Foo bar] bool doExactId = !fieldSpecificQueries.Any(); Query generalQuery = BuildGeneralQuery(doExactId, searchFilter.SearchTerm, analyzer, generalTerms, generalQueries); // IF field targeting is done, we should basically want to AND their field specific queries with all other query terms if (fieldSpecificQueries.Any()) { var combinedQuery = new BooleanQuery(); if (!IsDegenerateQuery(generalQuery)) { combinedQuery.Add(generalQuery, Occur.MUST); } foreach (var fieldQuery in fieldSpecificQueries) { if (!IsDegenerateQuery(fieldQuery)) { combinedQuery.Add(fieldQuery, Occur.MUST); } } generalQuery = combinedQuery; } return generalQuery; }