/// <summary> /// Searches the index. /// </summary> /// <param name="totalHits">The total hits.</param> /// <param name="forumId">The forum identifier.</param> /// <param name="userId">The user identifier.</param> /// <param name="searchQuery">The search query.</param> /// <param name="searchField">The search field.</param> /// <param name="pageIndex">Index of the page.</param> /// <param name="pageSize">Size of the page.</param> /// <returns> /// Returns the Search results /// </returns> private List <SearchMessage> SearchIndex( out int totalHits, int forumId, int userId, string searchQuery, string searchField = "", int pageIndex = 1, int pageSize = 1000) { if (searchQuery.Replace("*", string.Empty).Replace("?", string.Empty).IsNotSet()) { totalHits = 0; return(new List <SearchMessage>()); } // Insert forum access here var userAccessList = this.GetRepository <vaccess>().Get(v => v.UserID == userId); // filter forum if (forumId > 0) { userAccessList = userAccessList.FindAll(v => v.ForumID == forumId); } var searcher = this.GetSearcher(); if (searcher == null) { totalHits = 0; return(new List <SearchMessage>()); } var hitsLimit = this.Get <BoardSettings>().ReturnSearchMax; // 0 => Lucene error; if (hitsLimit == 0) { hitsLimit = pageSize; } var analyzer = new StandardAnalyzer(MatchVersion); var formatter = new SimpleHTMLFormatter("<mark>", "</mark>"); var fragmenter = new SimpleFragmenter(hitsLimit); QueryScorer scorer; // search by single field if (searchField.IsSet()) { var parser = new QueryParser(MatchVersion, searchField, analyzer); var query = ParseQuery(searchQuery, parser); scorer = new QueryScorer(query); var hits = searcher.Search(query, hitsLimit).ScoreDocs; totalHits = hits.Length; var highlighter = new Highlighter(formatter, scorer) { TextFragmenter = fragmenter }; var results = this.MapSearchToDataList( highlighter, analyzer, searcher, hits, pageIndex, pageSize, userAccessList); analyzer.Dispose(); return(results); } else { var parser = new MultiFieldQueryParser( MatchVersion, new[] { "Message", "Topic", this.Get <BoardSettings>().EnableDisplayName ? "AuthorDisplay" : "Author", "TopicTags" }, analyzer); var query = ParseQuery(searchQuery, parser); scorer = new QueryScorer(query); // sort by date var sort = new Sort(new SortField("MessageId", SortFieldType.STRING, true)); var fil = new BooleanFilter(); // search this forum if (forumId > 0) { fil.Add(new FilterClause(new TermsFilter(new Term("ForumId", forumId.ToString())), Occur.SHOULD)); } else { // filter user access if (userAccessList.Any()) { userAccessList.Where(a => !a.ReadAccess).ForEach( access => fil.Add( new FilterClause( new TermsFilter(new Term("ForumId", access.ForumID.ToString())), Occur.MUST_NOT))); } } var hits = searcher.Search(query, fil.Any() ? fil : null, hitsLimit, sort).ScoreDocs; totalHits = hits.Length; var highlighter = new Highlighter(formatter, scorer) { TextFragmenter = fragmenter }; var results = this.MapSearchToDataList( highlighter, analyzer, searcher, hits, pageIndex, pageSize, userAccessList); this.searcherManager.Release(searcher); return(results); } }
public async Task <AdminSearchResult> SearchContent(AdminSearchContext searchContext) { var searchResult = new AdminSearchResult(); await _luceneIndexProvider.SearchAsync(searchContext.Index, async searcher => { Query query; if (string.IsNullOrWhiteSpace(searchContext.SearchTerm)) { query = new MatchAllDocsQuery(); } else { var luceneVersion = LuceneSettings.DefaultVersion; var analyzer = new StandardAnalyzer(luceneVersion); var multiFieldQuery = new MultiFieldQueryParser(luceneVersion, searchContext.IndexFieldsToSearch, analyzer); query = multiFieldQuery.Parse(QueryParserBase.Escape(searchContext.SearchTerm)); } searchContext.PageNumber -= 1; var start = searchContext.PageNumber * searchContext.PageSize; var end = searchContext.PageNumber * searchContext.PageSize + searchContext.PageSize; var collector = TopScoreDocCollector.Create(end, true); var filter = new BooleanFilter(); if (searchContext.ContentTypes.Any()) { filter.Add(new FieldCacheTermsFilter("Content.ContentItem.ContentType", searchContext.ContentTypes), Occur.MUST); } if (searchContext.Filters != null && searchContext.Filters.Any()) { await _searchFilters.InvokeAsync(x => x.Filter(searchContext, filter), null); } if (filter.Any()) { searcher.Search(query, filter, collector); } else { searcher.Search(query, collector); } var docs = collector.GetTopDocs(start, end); searchResult.TotalRecordCount = docs.TotalHits; var contentItemIds = docs.ScoreDocs.Select(hit => { var doc = searcher.Doc(hit.Doc); return(doc.GetField("ContentItemId").GetStringValue()); }); searchResult.ContentItems = await _contentManager.GetAsync(contentItemIds); }); return(searchResult); }