コード例 #1
0
        private void BindSearch()
        {
            queryErrorOccurred = false;

            mojoPortal.SearchIndex.IndexItemCollection searchResults = mojoPortal.SearchIndex.IndexHelper.Search(
                siteSettings.SiteId,
                isSiteEditor,
                GetUserRoles(),
                config.GetFeatureGuids(),
                modifiedBeginDate,
                modifiedEndDate,
                txtSearch.Text,
                WebConfigSettings.EnableSearchResultsHighlighting,
                WebConfigSettings.SearchResultsFragmentSize,
                pageNumber,
                pageSize,
                WebConfigSettings.SearchMaxClauseCount,
                out totalHits,
                out queryErrorOccurred);

            totalPages = 1;

            if (pageSize > 0)
            {
                totalPages = totalHits / pageSize;
            }

            if (totalHits <= pageSize)
            {
                totalPages = 1;
            }
            else
            {
                int remainder;
                Math.DivRem(totalHits, pageSize, out remainder);
                if (remainder > 0)
                {
                    totalPages += 1;
                }
            }


            pgr.ShowFirstLast = true;
            pgr.PageSize      = pageSize;
            pgr.PageCount     = totalPages;
            pgr.Visible       = (totalPages > 1);



            rptResults.DataSource = searchResults;
            rptResults.DataBind();

            updPnl.Update();
        }
コード例 #2
0
ファイル: IndexHelper.cs プロジェクト: joedavis01/mojoportal
        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;
            }
        }
コード例 #3
0
ファイル: IndexHelper.cs プロジェクト: joedavis01/mojoportal
        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;
        }
コード例 #4
0
        private void DoSearch(HttpContext context)
        {
            // this is only to make sure its initialized
            // before indexing is queued on a thread
            // because there is no HttpContext on
            // external threads and httpcontext is needed to initilaize
            // once initialized its cached
            IndexBuilderProviderCollection
                indexProviders = IndexBuilderManager.Providers;

            searchResults = mojoPortal.SearchIndex.IndexHelper.Search(
                siteSettings.SiteId,
                isSiteEditor,
                GetUserRoles(context),
                featureGuid,
                modifiedBeginDate,
                modifiedEndDate,
                query,
                false,
                WebConfigSettings.SearchResultsFragmentSize,
                pageNumber,
                pageSize,
                WebConfigSettings.SearchMaxClauseCount,
                out totalHits,
                out queryErrorOccurred);

            start = 1;
            if (pageNumber > 1)
            {
                start = ((pageNumber - 1) * pageSize) + 1;
            }

            end = pageSize;
            if (start > 1) { end += start; }

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

            totalPages = 1;
            int pageLowerBound = (pageSize * pageNumber) - pageSize;

            if (pageSize > 0) { totalPages = totalHits / pageSize; }

            if (totalHits <= pageSize)
            {
                totalPages = 1;
            }
            else
            {
                int remainder;
                Math.DivRem(totalHits, pageSize, out remainder);
                if (remainder > 0)
                {
                    totalPages += 1;
                }
            }
        }
コード例 #5
0
        private void RenderSearchResults(HttpContext context, mojoPortal.SearchIndex.IndexItemCollection searchResults)
        {
            context.Response.ContentType = "application/xml";
            Encoding encoding = new UTF8Encoding();

            context.Response.ContentEncoding = encoding;

            string sanitizedQuery = SecurityHelper.RemoveMarkup(query);

            using (XmlTextWriter xmlTextWriter = new XmlTextWriter(context.Response.OutputStream, encoding))
            {
                xmlTextWriter.Formatting = Formatting.Indented;

                xmlTextWriter.WriteStartDocument();

                xmlTextWriter.WriteStartElement("feed");
                xmlTextWriter.WriteAttributeString("xmlns", "http://www.w3.org/2005/Atom");
                xmlTextWriter.WriteAttributeString("xmlns:opensearch", "http://a9.com/-/spec/opensearch/1.1/");

                xmlTextWriter.WriteStartElement("title");
                xmlTextWriter.WriteValue(string.Format(CultureInfo.InvariantCulture, Resource.SearchTitleFormat, siteSettings.SiteName, sanitizedQuery));
                xmlTextWriter.WriteEndElement();

                xmlTextWriter.WriteStartElement("link");
                xmlTextWriter.WriteAttributeString("href", SiteRoot + "/SearchResults.ashx?q=" + context.Server.UrlEncode(sanitizedQuery));
                xmlTextWriter.WriteEndElement();

                xmlTextWriter.WriteStartElement("updated");
                xmlTextWriter.WriteValue(DateTime.UtcNow.ToString("u", CultureInfo.InvariantCulture).Replace(" ", "T"));
                xmlTextWriter.WriteEndElement();


                xmlTextWriter.WriteStartElement("author");

                xmlTextWriter.WriteStartElement("name");
                xmlTextWriter.WriteValue(siteSettings.CompanyName);
                xmlTextWriter.WriteEndElement();
                xmlTextWriter.WriteEndElement();

                xmlTextWriter.WriteStartElement("id");
                xmlTextWriter.WriteValue("urn:uuid:" + siteSettings.SiteGuid.ToString());
                xmlTextWriter.WriteEndElement();

                xmlTextWriter.WriteStartElement("opensearch:totalResults");
                xmlTextWriter.WriteValue(totalHits.ToString(CultureInfo.InvariantCulture));
                xmlTextWriter.WriteEndElement();

                xmlTextWriter.WriteStartElement("opensearch:startIndex");
                xmlTextWriter.WriteValue(start.ToString(CultureInfo.InvariantCulture));
                xmlTextWriter.WriteEndElement();

                xmlTextWriter.WriteStartElement("opensearch:itemsPerPage");
                xmlTextWriter.WriteValue(pageSize.ToString(CultureInfo.InvariantCulture));
                xmlTextWriter.WriteEndElement();

                xmlTextWriter.WriteStartElement("opensearch:Query");
                xmlTextWriter.WriteAttributeString("role", "request");
                xmlTextWriter.WriteAttributeString("searchTerms", sanitizedQuery);
                xmlTextWriter.WriteAttributeString("startPage", "1");
                xmlTextWriter.WriteEndElement();

                //this is a link to the xhtml search page
                xmlTextWriter.WriteStartElement("link");
                xmlTextWriter.WriteAttributeString("rel", "alternate");
                xmlTextWriter.WriteAttributeString("href", SiteRoot + "/SearchResults.aspx?q="
                                                   + context.Server.UrlEncode(sanitizedQuery)
                                                   + "&p=" + pageNumber.ToString(CultureInfo.InvariantCulture));
                xmlTextWriter.WriteAttributeString("type", "text/html");
                xmlTextWriter.WriteEndElement();

                xmlTextWriter.WriteStartElement("link");
                xmlTextWriter.WriteAttributeString("rel", "self");
                xmlTextWriter.WriteAttributeString("href", SiteRoot + "/SearchResults.ashx?q="
                                                   + context.Server.UrlEncode(sanitizedQuery)
                                                   + "&p=" + pageNumber.ToString(CultureInfo.InvariantCulture));
                xmlTextWriter.WriteAttributeString("type", "application/atom+xml");
                xmlTextWriter.WriteEndElement();

                if (totalPages > 1)
                {
                    xmlTextWriter.WriteStartElement("link");
                    xmlTextWriter.WriteAttributeString("rel", "first");
                    xmlTextWriter.WriteAttributeString("href", SiteRoot + "/SearchResults.ashx?q="
                                                       + context.Server.UrlEncode(sanitizedQuery)
                                                       + "&p=1");
                    xmlTextWriter.WriteAttributeString("type", "application/atom+xml");
                    xmlTextWriter.WriteEndElement();

                    if (pageNumber > 1)
                    {
                        xmlTextWriter.WriteStartElement("link");
                        xmlTextWriter.WriteAttributeString("rel", "previous");
                        xmlTextWriter.WriteAttributeString("href", SiteRoot + "/SearchResults.ashx?q="
                                                           + context.Server.UrlEncode(sanitizedQuery)
                                                           + "&p=" + (pageNumber - 1).ToString(CultureInfo.InvariantCulture));
                        xmlTextWriter.WriteAttributeString("type", "application/atom+xml");
                        xmlTextWriter.WriteEndElement();
                    }

                    if (pageNumber < totalPages)
                    {
                        xmlTextWriter.WriteStartElement("link");
                        xmlTextWriter.WriteAttributeString("rel", "next");
                        xmlTextWriter.WriteAttributeString("href", SiteRoot + "/SearchResults.ashx?q="
                                                           + context.Server.UrlEncode(sanitizedQuery)
                                                           + "&p=" + (pageNumber + 1).ToString(CultureInfo.InvariantCulture));
                        xmlTextWriter.WriteAttributeString("type", "application/atom+xml");
                        xmlTextWriter.WriteEndElement();
                    }

                    xmlTextWriter.WriteStartElement("link");
                    xmlTextWriter.WriteAttributeString("rel", "last");
                    xmlTextWriter.WriteAttributeString("href", SiteRoot + "/SearchResults.ashx?q="
                                                       + context.Server.UrlEncode(sanitizedQuery)
                                                       + "&p=" + totalPages.ToString(CultureInfo.InvariantCulture));
                    xmlTextWriter.WriteAttributeString("type", "application/atom+xml");
                    xmlTextWriter.WriteEndElement();
                }

                ////this is a  link to the description
                xmlTextWriter.WriteStartElement("link");
                xmlTextWriter.WriteAttributeString("rel", "search");
                xmlTextWriter.WriteAttributeString("type", "application/opensearchdescription+xml");
                xmlTextWriter.WriteAttributeString("href", SiteRoot + "/SearchEngineInfo.ashx");
                xmlTextWriter.WriteEndElement();


                foreach (mojoPortal.SearchIndex.IndexItem item in searchResults)
                {
                    xmlTextWriter.WriteStartElement("entry");

                    xmlTextWriter.WriteStartElement("link");
                    xmlTextWriter.WriteValue(BuildUrl(item));
                    xmlTextWriter.WriteEndElement();

                    xmlTextWriter.WriteStartElement("id");
                    xmlTextWriter.WriteValue(BuildUrl(item));
                    xmlTextWriter.WriteEndElement();


                    //xmlTextWriter.WriteRaw("<updated>2003-12-13T18:30:02Z</updated>");

                    xmlTextWriter.WriteStartElement("content");
                    xmlTextWriter.WriteAttributeString("type", "text");
                    xmlTextWriter.WriteCData(item.Intro);
                    xmlTextWriter.WriteEndElement();


                    xmlTextWriter.WriteEndElement();
                }

                xmlTextWriter.WriteEndElement();
            }
        }
コード例 #6
0
        private void DoSearch(HttpContext context)
        {
            // this is only to make sure its initialized
            // before indexing is queued on a thread
            // because there is no HttpContext on
            // external threads and httpcontext is needed to initilaize
            // once initialized its cached
            IndexBuilderProviderCollection
                indexProviders = IndexBuilderManager.Providers;


            searchResults = mojoPortal.SearchIndex.IndexHelper.Search(
                siteSettings.SiteId,
                isSiteEditor,
                GetUserRoles(context),
                featureGuid,
                modifiedBeginDate,
                modifiedEndDate,
                query,
                false,
                WebConfigSettings.SearchResultsFragmentSize,
                pageNumber,
                pageSize,
                WebConfigSettings.SearchMaxClauseCount,
                out totalHits,
                out queryErrorOccurred);

            start = 1;
            if (pageNumber > 1)
            {
                start = ((pageNumber - 1) * pageSize) + 1;
            }

            end = pageSize;
            if (start > 1)
            {
                end += start;
            }

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

            totalPages = 1;
            int pageLowerBound = (pageSize * pageNumber) - pageSize;

            if (pageSize > 0)
            {
                totalPages = totalHits / pageSize;
            }

            if (totalHits <= pageSize)
            {
                totalPages = 1;
            }
            else
            {
                int remainder;
                Math.DivRem(totalHits, pageSize, out remainder);
                if (remainder > 0)
                {
                    totalPages += 1;
                }
            }
        }
コード例 #7
0
        private void DoSearch()
        {
            if (Page.IsPostBack)
            {
                return;
            }

            if (Request.QueryString.Get("q") == null)
            {
                return;
            }

            query = Request.QueryString.Get("q");

            if (this.query.Length == 0)
            {
                return;
            }



            //txtSearchInput.Text = Server.HtmlEncode(query).Replace("&quot;", "\"") ;
            txtSearchInput.Text = SecurityHelper.SanitizeHtml(query);


            // this is only to make sure its initialized
            // before indexing is queued on a thread
            // because there is no HttpContext on
            // external threads and httpcontext is needed to initilaize
            // once initialized its cached
            IndexBuilderProviderCollection
                indexProviders = IndexBuilderManager.Providers;

            queryErrorOccurred = false;

            mojoPortal.SearchIndex.IndexItemCollection searchResults = mojoPortal.SearchIndex.IndexHelper.Search(
                siteSettings.SiteId,
                isSiteEditor,
                GetUserRoles(),
                featureGuid,
                modifiedBeginDate,
                modifiedEndDate,
                query,
                WebConfigSettings.EnableSearchResultsHighlighting,
                WebConfigSettings.SearchResultsFragmentSize,
                pageNumber,
                pageSize,
                WebConfigSettings.SearchMaxClauseCount,
                out totalHits,
                out queryErrorOccurred);

            if (searchResults.Count == 0)
            {
                ShowNoResults();
                InitIndexIfNeeded();
                return;
            }

            int start = 1;

            if (pageNumber > 1)
            {
                start = ((pageNumber - 1) * pageSize) + 1;
            }

            int end = pageSize;

            if (start > 1)
            {
                end += start;
            }

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

            this.pnlSearchResults.Visible = true;
            this.pnlNoResults.Visible     = false;
            this.lblDuration.Visible      = true;
            this.lblSeconds.Visible       = true;

            this.lblFrom.Text      = (start).ToString();
            this.lblTo.Text        = end.ToString(CultureInfo.InvariantCulture);
            this.lblTotal.Text     = totalHits.ToString(CultureInfo.InvariantCulture);
            this.lblQueryText.Text = Server.HtmlEncode(query);
            float duration = searchResults.ExecutionTime * 0.0000001F;

            this.lblDuration.Text = duration.ToString();
            divResults.Visible    = true;

            totalPages = 1;
            //int pageLowerBound = (pageSize * pageNumber) - pageSize;

            if (pageSize > 0)
            {
                totalPages = totalHits / pageSize;
            }

            if (totalHits <= pageSize)
            {
                totalPages = 1;
            }
            else
            {
                int remainder;
                Math.DivRem(totalHits, pageSize, out remainder);
                if (remainder > 0)
                {
                    totalPages += 1;
                }
            }

            //totalPages always seems 1 more than it should be not sure why
            //if (totalPages > 1) { totalPages -= 1; }

            string searchUrl = SiteRoot
                               + "/SearchResults.aspx?q=" + Server.UrlEncode(query)
                               + "&amp;p={0}"
                               + GetModBeginDateParam(true)
                               + GetModEndDateParam(true)
                               + GetFeatureParam(true);

            pgrTop.PageURLFormat = searchUrl;
            pgrTop.ShowFirstLast = true;
            pgrTop.CurrentIndex  = pageNumber;
            pgrTop.PageSize      = pageSize;
            pgrTop.PageCount     = totalPages;
            pgrTop.Visible       = (totalPages > 1);

            pgrBottom.PageURLFormat = searchUrl;
            pgrBottom.ShowFirstLast = true;
            pgrBottom.CurrentIndex  = pageNumber;
            pgrBottom.PageSize      = pageSize;
            pgrBottom.PageCount     = totalPages;
            pgrBottom.Visible       = (totalPages > 1);



            this.rptResults.DataSource = searchResults;
            this.rptResults.DataBind();
        }