Пример #1
0
        /// <summary>
        ///     For objects matching your query
        /// </summary>
        public SearchResultSet <Post> Search(SearchQuery searchQuery)
        {
            var searchResults = new SearchResultSet <Post>();

            if (String.IsNullOrWhiteSpace(searchQuery.QueryText))
            {
                return(searchResults);
            }

            DateTime      dt        = DateTime.Now;
            string        queryText = searchQuery.QueryText;
            IndexSearcher searcher  = null;

            EnsureIndexExists();

            var parser = GetQueryParser();

            foreach (var specialCharacter in specialLuceneCharacters)
            {
                if (queryText.Contains(specialCharacter))
                {
                    queryText = queryText.Replace(specialCharacter, @"\" + specialCharacter);
                }
            }
            queryText = _andRegex.Replace(queryText, " AND ");
            queryText = _orRegex.Replace(queryText, " OR ");

            var query = parser.Parse(queryText);

            if (String.IsNullOrWhiteSpace(query.ToString()))
            {
                return(searchResults);
            }

            lck.AcquireReaderLock(ReaderTimeOut);
            try
            {
                searcher = new IndexSearcher(rd);
                TopDocs hits = searcher.Search(query, searchQuery.MaxResults);

                searchResults.TotalRecords = hits.TotalHits;
                TimeSpan ts = (DateTime.Now - dt);
                searchResults.SearchDuration = ts.Milliseconds;

                if (hits.ScoreDocs.Length <= 0)
                {
                    return(searchResults);
                }

                var formatter = new SimpleHTMLFormatter(":openhighlight", ":closehighlight");
                //use placeholders instead of html to allow later htmlencode
                var highlighter = new Highlighter(formatter, new QueryScorer(query));

                int start = (searchQuery.PageIndex - 1) * searchQuery.PageSize;
                int end   = searchQuery.PageIndex * searchQuery.PageSize;

                if (start > hits.ScoreDocs.Length)
                {
                    start = hits.ScoreDocs.Length;
                }

                if (end > hits.ScoreDocs.Length)
                {
                    end = hits.ScoreDocs.Length;
                }

                for (int i = start; i < end; i++)
                {
                    var doc = searcher.Doc(hits.ScoreDocs[i].Doc);
                    searchResults.Add(CreatePostFromDocument(doc, highlighter));
                }

                return(searchResults);
            }
            catch (LQ.ParseException)
            {
                // Used to retry here... but now we escape query up-front
                throw;
            }
            finally
            {
                if (searcher != null)
                {
                    searcher.Dispose();
                }

                lck.ReleaseReaderLock();
            }
        }
Пример #2
0
        protected virtual SearchResultSet <Post> Search(SearchQuery sq, bool reSearch)
        {
            DateTime      dt       = DateTime.Now;
            string        _sq      = sq.QueryText;
            IndexSearcher searcher = null;

            if (rd == null)
            {
                BuildIndex();
            }

            lck.AcquireReaderLock(ReaderTimeOut);
            try
            {
                Analyzer analyzer = GetAnalyzer();

                _sq = _andRegex.Replace(_sq, " AND ");
                _sq = _orRegex.Replace(_sq, " OR ");

                QueryParser parser = GetQueryParser(analyzer);
                parser.SetDefaultOperator(QueryParser.AND_OPERATOR);
                Query q = parser.Parse(_sq);
                searcher = new IndexSearcher(rd, true);

                Query   filterQuery = GetFilterQuery(sq);
                LFilter theFilter   = null;
                if (filterQuery != null)
                {
                    theFilter = new LFilter(filterQuery);
                }

                //TODO: replace next line by:
                //  Lucene.Net.Search.TopFieldDocs hits = Search(Lucene.Net.Search.Weight weight, Lucene.Net.Search.Filter filter,
                //                                               int nDocs, Lucene.Net.Search.Sort sort)
#pragma warning disable CS0618 // Type or member is obsolete
                Hits hits = searcher.Search(q, theFilter, GetSort(sq));
#pragma warning restore CS0618 // Type or member is obsolete

                SearchResultSet <Post> searchResults = new SearchResultSet <Post>();

                searchResults.TotalRecords = hits.Length();
                TimeSpan ts = (DateTime.Now - dt);
                searchResults.SearchDuration = ts.Milliseconds;

                SimpleHTMLFormatter html        = new SimpleHTMLFormatter(":openhighlight", ":closehighlight");          //use placeholders instead of html to allow later htmlencode
                Highlighter         highlighter = new Highlighter(html, new QueryScorer(q));

                int start = (sq.PageIndex - 1) * sq.PageSize;
                int end   = sq.PageIndex * sq.PageSize;

                if (start > hits.Length())
                {
                    start = hits.Length();
                }

                if (end > hits.Length())
                {
                    end = hits.Length();
                }

                for (int i = start; i < end; i++)
                {
                    Document doc = hits.Doc(i);
                    searchResults.Add(CreateFromDocument(doc, analyzer, highlighter));
                }

                return(searchResults);
            }
            catch (Lucene.Net.QueryParsers.ParseException)
            {
                if (reSearch)
                {
                    sq.QueryText = _escape.Replace(sq.QueryText, "\\$1");
                    Search(sq, false);
                }
                else
                {
                    throw;
                }
            }
            finally
            {
                if (searcher != null)
                {
                    searcher.Close();
                }


                lck.ReleaseReaderLock();
            }

            return(null);
        }