Beispiel #1
0
        public static IndexItemCollection Search(
            int siteId,
            bool isAdminContentAdminOrSiteEditor,
            List<string> userRoles,
            Guid[] featureGuids,
            DateTime modifiedBeginDate,
            DateTime modifiedEndDate,
            string queryText,
            bool highlightResults,
            int highlightedFragmentSize,
            int pageNumber,
            int pageSize,
            int maxClauseCount,
            out int totalHits,
            out bool invalidQuery)
        {
            invalidQuery = false;
            totalHits = 0;

            IndexItemCollection results = new IndexItemCollection();

            if (string.IsNullOrEmpty(queryText))
            {
                return results;
            }

            using (Lucene.Net.Store.Directory searchDirectory = GetDirectory(siteId))
            {
                if (!IndexReader.IndexExists(searchDirectory)) { return results; }

                long startTicks = DateTime.Now.Ticks;

                try
                {
                    if (maxClauseCount != 1024)
                    {
                        BooleanQuery.MaxClauseCount = maxClauseCount;
                    }

                    // there are different analyzers for different languages
                    // see LuceneSettings.config in the root of the web
                    LuceneSettingsProvider provider = LuceneSettingsManager.Providers[GetSiteProviderName(siteId)];
                    Analyzer analyzer = provider.GetAnalyzer();

                    Query searchQuery = MultiFieldQueryParser.Parse(
                        Lucene.Net.Util.Version.LUCENE_30,
                        new string[] { queryText, queryText, queryText, queryText, queryText, queryText.Replace("*", string.Empty) },
                        new string[] { "Title", "ModuleTitle", "contents", "PageName", "PageMetaDesc", "Keyword" },
                        analyzer);

                    BooleanQuery filterQuery = new BooleanQuery(); // won't be used to score the results

                    if (!isAdminContentAdminOrSiteEditor) // skip role filters for these users
                    {
                        AddRoleFilters(userRoles, filterQuery);
                        AddModuleRoleFilters(userRoles, filterQuery);
                    }

                    TermRangeQuery beginDateFilter = new TermRangeQuery(
                        "PublishBeginDate",
                        DateTime.MinValue.ToString("s"),
                        DateTime.UtcNow.ToString("s"),
                        true,
                        true);

                    filterQuery.Add(beginDateFilter, Occur.MUST);

                    TermRangeQuery endDateFilter = new TermRangeQuery(
                        "PublishEndDate",
                        DateTime.UtcNow.ToString("s"),
                        DateTime.MaxValue.ToString("s"),
                        true,
                        true);

                    filterQuery.Add(endDateFilter, Occur.MUST);

                    if ((modifiedBeginDate.Date > DateTime.MinValue.Date) || (modifiedEndDate.Date < DateTime.MaxValue.Date))
                    {
                        TermRangeQuery lastModifiedDateFilter = new TermRangeQuery(
                            "LastModUtc",
                            modifiedBeginDate.Date.ToString("s"),
                            modifiedEndDate.Date.ToString("s"),
                            true,
                            true);

                        filterQuery.Add(lastModifiedDateFilter, Occur.MUST);
                    }

                    //if ((!DisableSearchFeatureFilters) && (featureGuid != Guid.Empty))
                    //{
                    //    BooleanQuery featureFilter = new BooleanQuery();

                    //    featureFilter.Add(new TermQuery(new Term("FeatureId", featureGuid.ToString())), Occur.MUST);

                    //    filterQuery.Add(featureFilter, Occur.MUST);
                    //}

                    if ((featureGuids != null) && (featureGuids.Length > 0))
                    {
                        BooleanQuery featureFilter = new BooleanQuery();

                        foreach (Guid featureGuid in featureGuids)
                        {
                            featureFilter.Add(new TermQuery(new Term("FeatureId", featureGuid.ToString())), Occur.SHOULD);
                        }

                        filterQuery.Add(featureFilter, Occur.MUST);
                    }

                    Filter filter = new QueryWrapperFilter(filterQuery); // filterQuery won't affect result scores

                    using (IndexSearcher searcher = new IndexSearcher(searchDirectory))
                    {

                        //http://stackoverflow.com/questions/9872933/migrating-lucene-hitcollector-2-x-to-collector-3-x
                        //TopScoreDocCollector collector = TopScoreDocCollector.Create(maxResults, true);

                        int maxResults = int.MaxValue;
                        TopDocs hits = searcher.Search(searchQuery, filter, maxResults);

                        int startHit = 0;
                        if (pageNumber > 1)
                        {
                            startHit = ((pageNumber - 1) * pageSize);
                        }

                        totalHits = hits.TotalHits;

                        int end = startHit + pageSize;
                        if (totalHits <= end)
                        {
                            end = totalHits;
                        }

                        int itemsAdded = 0;
                        int itemsToAdd = end;

                        QueryScorer scorer = new QueryScorer(searchQuery);
                        SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span class='searchterm'>", "</span>");
                        Highlighter highlighter = new Highlighter(formatter, scorer);

                        highlighter.TextFragmenter = new SimpleFragmenter(highlightedFragmentSize);

                        for (int i = startHit; i < itemsToAdd; i++)
                        {
                            Document doc = searcher.Doc(hits.ScoreDocs[i].Doc);
                            IndexItem indexItem = new IndexItem(doc, hits.ScoreDocs[i].Score);

                            if (highlightResults)
                            {
                                try
                                {
                                    TokenStream stream = analyzer.TokenStream("contents", new StringReader(doc.Get("contents")));
                                    string highlightedResult = highlighter.GetBestFragment(stream, doc.Get("contents"));

                                    if (highlightedResult != null) { indexItem.Intro = highlightedResult; }
                                }
                                catch (NullReferenceException) { }
                            }

                            results.Add(indexItem);
                            itemsAdded += 1;

                        }

                        results.ItemCount = itemsAdded;
                        results.PageIndex = pageNumber;

                        results.ExecutionTime = DateTime.Now.Ticks - startTicks;

                    }

                }
                catch (ParseException ex)
                {
                    invalidQuery = true;
                    log.Error("handled error for search terms " + queryText, ex);
                    // these parser exceptions are generally caused by
                    // spambots posting too much junk into the search form
                    // heres an option to automatically ban the ip address
                    HandleSpam(queryText, ex);

                    return results;
                }
                catch (BooleanQuery.TooManyClauses ex)
                {
                    invalidQuery = true;
                    log.Error("handled error for search terms " + queryText, ex);
                    return results;

                }
                catch (System.IO.IOException ex)
                {
                    invalidQuery = true;
                    log.Error("handled error for search terms " + queryText, ex);
                    return results;

                }

                return results;
            }
        }
Beispiel #2
0
        public static IndexItemCollection Browse(
            int siteId,
            Guid featureGuid,
            DateTime modifiedBeginDate,
            DateTime modifiedEndDate,
            int pageNumber,
            int pageSize,
            out int totalHits)
        {
            totalHits = 0;

            IndexItemCollection results = new IndexItemCollection();

            using (Lucene.Net.Store.Directory searchDirectory = GetDirectory(siteId))
            {
                Filter filter = null;
                BooleanQuery filterQuery = null;

                if ((modifiedBeginDate.Date > DateTime.MinValue.Date) || (modifiedEndDate.Date < DateTime.MaxValue.Date))
                {
                    filterQuery = new BooleanQuery(); // won't be used to score the results

                    TermRangeQuery lastModifiedDateFilter = new TermRangeQuery(
                        "LastModUtc",
                        modifiedBeginDate.Date.ToString("s"),
                        modifiedEndDate.Date.ToString("s"),
                        true,
                        true);

                    filterQuery.Add(lastModifiedDateFilter, Occur.MUST);

                }

                if (featureGuid != Guid.Empty)
                {
                    if (filterQuery == null) { filterQuery = new BooleanQuery(); }

                    BooleanQuery featureFilter = new BooleanQuery();

                    featureFilter.Add(new TermQuery(new Term("FeatureId", featureGuid.ToString())), Occur.MUST);

                    filterQuery.Add(featureFilter, Occur.MUST);
                }

                if (filterQuery != null)
                {
                    filter = new QueryWrapperFilter(filterQuery); // filterQuery won't affect result scores
                }

                MatchAllDocsQuery matchAllQuery = new MatchAllDocsQuery();

                using (IndexSearcher searcher = new IndexSearcher(searchDirectory))
                {
                    int maxResults = int.MaxValue;

                    TopDocs hits = searcher.Search(matchAllQuery, filter, maxResults);

                    int startHit = 0;
                    if (pageNumber > 1)
                    {
                        startHit = ((pageNumber - 1) * pageSize);
                    }

                    totalHits = hits.TotalHits;

                    if (startHit > totalHits)
                    {
                        startHit = totalHits;
                    }

                    int end = startHit + pageSize;
                    if (totalHits <= end)
                    {
                        end = totalHits;
                    }

                    int itemsAdded = 0;
                    int itemsToAdd = end;

                    for (int i = startHit; i < itemsToAdd; i++)
                    {
                        Document doc = searcher.Doc(hits.ScoreDocs[i].Doc);
                        IndexItem indexItem = new IndexItem(doc, hits.ScoreDocs[i].Score);

                        results.Add(indexItem);
                        itemsAdded += 1;

                    }

                    results.ItemCount = itemsAdded;
                    results.PageIndex = pageNumber;

                    results.ExecutionTime = DateTime.Now.Ticks; // -0;

                }

                //    using (IndexReader reader = IndexReader.Open(searchDirectory, false))
                //    {

                //        totalHits = reader.NumDocs();
                //        int startHit = 0;
                //        int itemsToAdd = pageSize;
                //        if (pageNumber > 1)
                //        {
                //            startHit = ((pageNumber - 1) * pageSize);
                //            int end = startHit + pageSize;
                //            if (totalHits <= end)
                //            {
                //                end = totalHits;
                //            }
                //            itemsToAdd = end;
                //        }

                //        for (int i = startHit; i < itemsToAdd; i++)
                //        {
                //            Document doc = reader.Document(i);
                //            IndexItem indexItem = new IndexItem(doc, 1);
                //            results.Add(indexItem);
                //        }

                //    }

            }

            return results;
        }