/// <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(); } }
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); }