private Tuple <int, IList <SearchResult> > GetResults(SearchQuery searchQuery) { Requires.NotNull("Query", searchQuery); Requires.PropertyNotEqualTo("searchQuery", "SearchTypeIds", searchQuery.SearchTypeIds.Count(), 0); if ((searchQuery.ModuleId > 0) && (searchQuery.SearchTypeIds.Count() > 1 || !searchQuery.SearchTypeIds.Contains(_moduleSearchTypeId))) { throw new ArgumentException(Localization.Localization.GetExceptionMessage("ModuleIdMustHaveSearchTypeIdForModule", "ModuleId based search must have SearchTypeId for a module only")); } if (searchQuery.SortField == SortFields.CustomStringField || searchQuery.SortField == SortFields.CustomNumericField || searchQuery.SortField == SortFields.NumericKey || searchQuery.SortField == SortFields.Keyword) { Requires.NotNullOrEmpty("CustomSortField", searchQuery.CustomSortField); } var query = new BooleanQuery(); if (!string.IsNullOrEmpty(searchQuery.KeyWords)) { try { var allowLeadingWildcard = HostController.Instance.GetString("Search_AllowLeadingWildcard", "N") == "Y" || searchQuery.AllowLeadingWildcard; var keywords = SearchHelper.Instance.RephraseSearchText(searchQuery.KeyWords, searchQuery.WildCardSearch, allowLeadingWildcard); // don't use stemming analyzer for exact matches or non-analyzed fields (e.g. Tags) var analyzer = LuceneController.Instance.GetCustomAnalyzer() ?? new SearchQueryAnalyzer(true); var nonStemmerAnalyzer = new SearchQueryAnalyzer(false); var keywordQuery = new BooleanQuery(); foreach (var fieldToSearch in Constants.KeyWordSearchFields) { var parserContent = new QueryParser(Constants.LuceneVersion, fieldToSearch, fieldToSearch == Constants.Tag ? nonStemmerAnalyzer : analyzer); parserContent.AllowLeadingWildcard = allowLeadingWildcard; var parsedQueryContent = parserContent.Parse(keywords); keywordQuery.Add(parsedQueryContent, Occur.SHOULD); } query.Add(keywordQuery, Occur.MUST); } catch (Exception) { foreach (var word in searchQuery.KeyWords.Split(' ')) { query.Add(new TermQuery(new Term(Constants.ContentTag, word.ToLowerInvariant())), Occur.SHOULD); } } } var portalIdQuery = new BooleanQuery(); foreach (var portalId in searchQuery.PortalIds) { portalIdQuery.Add(NumericRangeQuery.NewIntRange(Constants.PortalIdTag, portalId, portalId, true, true), Occur.SHOULD); } if (searchQuery.PortalIds.Any()) { query.Add(portalIdQuery, Occur.MUST); } ApplySearchTypeIdFilter(query, searchQuery); if (searchQuery.BeginModifiedTimeUtc > DateTime.MinValue && searchQuery.EndModifiedTimeUtc >= searchQuery.BeginModifiedTimeUtc) { query.Add(NumericRangeQuery.NewLongRange(Constants.ModifiedTimeTag, long.Parse(searchQuery.BeginModifiedTimeUtc.ToString(Constants.DateTimeFormat)), long.Parse(searchQuery.EndModifiedTimeUtc.ToString(Constants.DateTimeFormat)), true, true), Occur.MUST); } if (searchQuery.RoleId > 0) { query.Add(NumericRangeQuery.NewIntRange(Constants.RoleIdTag, searchQuery.RoleId, searchQuery.RoleId, true, true), Occur.MUST); } foreach (var tag in searchQuery.Tags) { var text = tag.ToLowerInvariant(); if (HtmlUtils.ContainsEntity(text)) { text = System.Net.WebUtility.HtmlDecode(text); } query.Add(new TermQuery(new Term(Constants.Tag, text)), Occur.MUST); } foreach (var kvp in searchQuery.CustomKeywords) { query.Add(new TermQuery(new Term( SearchHelper.Instance.StripTagsNoAttributes(Constants.KeywordsPrefixTag + kvp.Key, true), kvp.Value)), Occur.MUST); } foreach (var kvp in searchQuery.NumericKeys) { query.Add(NumericRangeQuery.NewIntRange(Constants.NumericKeyPrefixTag + kvp.Key, kvp.Value, kvp.Value, true, true), Occur.MUST); } if (!string.IsNullOrEmpty(searchQuery.CultureCode)) { var localeQuery = new BooleanQuery(); var languageId = Localization.Localization.GetCultureLanguageID(searchQuery.CultureCode); localeQuery.Add(NumericRangeQuery.NewIntRange(Constants.LocaleTag, languageId, languageId, true, true), Occur.SHOULD); localeQuery.Add(NumericRangeQuery.NewIntRange(Constants.LocaleTag, Null.NullInteger, Null.NullInteger, true, true), Occur.SHOULD); query.Add(localeQuery, Occur.MUST); } var luceneQuery = new LuceneQuery { Query = query, Sort = GetSort(searchQuery), PageIndex = searchQuery.PageIndex, PageSize = searchQuery.PageSize, TitleSnippetLength = searchQuery.TitleSnippetLength, BodySnippetLength = searchQuery.BodySnippetLength }; return(GetSecurityTrimmedResults(searchQuery, luceneQuery)); }
private Tuple <int, IList <SearchResult> > GetResults(SearchQuery searchQuery) { Requires.NotNull("Query", searchQuery); Requires.PropertyNotEqualTo("searchQuery", "SearchTypeIds", searchQuery.SearchTypeIds.Count(), 0); if ((searchQuery.ModuleId > 0) && (searchQuery.SearchTypeIds.Count() > 1 || !searchQuery.SearchTypeIds.Contains(_moduleSearchTypeId))) { throw new ArgumentException("ModuleId based search must have SearchTypeId for a module only"); } //TODO - Explore Slop factor for Phrase query var query = new BooleanQuery(); if (!string.IsNullOrEmpty(searchQuery.KeyWords)) { try { var keywords = SearchHelper.Instance.RephraseSearchText(searchQuery.KeyWords, searchQuery.WildCardSearch); // don't use stemming analyzer for exact matches or non-analyzed fields (e.g. Tags) var analyzer = new SearchQueryAnalyzer(true); var nonStemmerAnalyzer = new SearchQueryAnalyzer(false); var keywordQuery = new BooleanQuery(); foreach (var fieldToSearch in Constants.KeyWordSearchFields) { var parserContent = new QueryParser(Constants.LuceneVersion, fieldToSearch, fieldToSearch == Constants.Tag ? nonStemmerAnalyzer : analyzer); var parsedQueryContent = parserContent.Parse(keywords); keywordQuery.Add(parsedQueryContent, Occur.SHOULD); } query.Add(keywordQuery, Occur.MUST); } catch (Exception) { foreach (var word in searchQuery.KeyWords.Split(' ')) { query.Add(new TermQuery(new Term(Constants.ContentTag, word.ToLower())), Occur.SHOULD); } } } var portalIdQuery = new BooleanQuery(); foreach (var portalId in searchQuery.PortalIds) { portalIdQuery.Add(NumericRangeQuery.NewIntRange(Constants.PortalIdTag, portalId, portalId, true, true), Occur.SHOULD); } if (searchQuery.PortalIds.Any()) { query.Add(portalIdQuery, Occur.MUST); } ApplySearchTypeIdFilter(query, searchQuery); if (searchQuery.BeginModifiedTimeUtc > DateTime.MinValue && searchQuery.EndModifiedTimeUtc >= searchQuery.BeginModifiedTimeUtc) { query.Add(NumericRangeQuery.NewLongRange(Constants.ModifiedTimeTag, long.Parse(searchQuery.BeginModifiedTimeUtc.ToString(Constants.DateTimeFormat)), long.Parse(searchQuery.EndModifiedTimeUtc.ToString(Constants.DateTimeFormat)), true, true), Occur.MUST); } if (searchQuery.RoleId > 0) { query.Add(NumericRangeQuery.NewIntRange(Constants.RoleIdTag, searchQuery.RoleId, searchQuery.RoleId, true, true), Occur.MUST); } foreach (var tag in searchQuery.Tags) { query.Add(new TermQuery(new Term(Constants.Tag, tag.ToLower())), Occur.MUST); } if (!string.IsNullOrEmpty(searchQuery.CultureCode)) { var localeQuery = new BooleanQuery(); var languageId = Localization.Localization.GetCultureLanguageID(searchQuery.CultureCode); localeQuery.Add(NumericRangeQuery.NewIntRange(Constants.LocaleTag, languageId, languageId, true, true), Occur.SHOULD); localeQuery.Add(NumericRangeQuery.NewIntRange(Constants.LocaleTag, Null.NullInteger, Null.NullInteger, true, true), Occur.SHOULD); query.Add(localeQuery, Occur.MUST); } var sort = Sort.RELEVANCE; if (searchQuery.SortField == SortFields.LastModified) { sort = new Sort(new SortField(Constants.ModifiedTimeTag, SortField.LONG, true)); } var luceneQuery = new LuceneQuery { Query = query, Sort = sort, PageIndex = searchQuery.PageIndex, PageSize = searchQuery.PageSize, TitleSnippetLength = searchQuery.TitleSnippetLength, BodySnippetLength = searchQuery.BodySnippetLength }; return(GetSecurityTrimmedResults(searchQuery, luceneQuery)); }