Esempio n. 1
0
        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));
        }