Ejemplo n.º 1
0
        /// <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);
            }
        }
Ejemplo n.º 2
0
        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);
        }