Пример #1
0
        public ActionResult Search(string query, int? page, string titlesonly)
        {
            var pageNumber = page ?? 1;
            if (pageNumber <= 0)
                pageNumber = 1;

            var q = new SearchQuery
            {
                Query = query,
                CurrentPage = pageNumber,
                TitlesOnly = !string.IsNullOrWhiteSpace(titlesonly),
            };

            var vm = new SearchResultsViewModel {Query = q, SearchResults = new List<SearchResultsViewModel.SearchResult>(), TotalResults = 0};
            try
            {
                vm = Core.Index.SearchWithSuggestions(q);
            }
            catch (ParseException ex)
            {
                ViewBag.ErrorMessage = "Error: " + ex.Message;
            }

            ViewBag.Query = q;

            return View(vm);
        }
Пример #2
0
        public static SearchResultsViewModel SearchWithSuggestions(SearchQuery searchQuery, bool suggestOnlyWhenNoResults = false)
        {
            var ret = new SearchResultsViewModel
                      	{
                      		SearchResults = new List<SearchResultsViewModel.SearchResult>(PageSize), Query = searchQuery
                      	};

            // Parse query, possibly throwing a ParseException
            Query query;
            if (searchQuery.TitlesOnly)
            {
                var qp = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "Title",
                                         new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29)
                                         );
                query = qp.Parse(searchQuery.Query);
            }
            else
            {
                query = MultiFieldQueryParser.Parse(Lucene.Net.Util.Version.LUCENE_29, searchQuery.Query,
                                                    SearchFields, SearchFlags,
                                                    new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29)
                                                    );
            }

            // Perform the actual search
            var tsdc = TopScoreDocCollector.create(PageSize * searchQuery.CurrentPage, true);
            Searcher.Search(query, tsdc);
            ret.TotalResults = tsdc.GetTotalHits();
            var hits = tsdc.TopDocs().ScoreDocs;

            // Do the suggestion magic
            if (suggestOnlyWhenNoResults && ret.TotalResults == 0 || (!suggestOnlyWhenNoResults))
            {
                ret.Suggestions = new List<string>();
                var spellChecker = new SpellChecker.Net.Search.Spell.SpellChecker(Searcher.GetIndexReader().Directory());

                // This is kind of a hack to get things working quickly
                // for real-world usage we probably want to get the analyzed terms from the Query object
                var individualTerms = searchQuery.Query.Split(new[] { ' ', '\t', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);

                foreach (var term in individualTerms)
                {
                    // we only specify field name if we actually got results,
                    // to improve suggestions relevancy
                    ret.Suggestions.AddRange(spellChecker.SuggestSimilar(term,
                                                                searchQuery.MaxSuggestions,
                                                                null,
                                                                ret.TotalResults == 0 ? null : "Title",
                                                                true));
                }
            }

            // Init the highlighter instance
            var fvh = new FastVectorHighlighter(FastVectorHighlighter.DEFAULT_PHRASE_HIGHLIGHT,
                                    FastVectorHighlighter.DEFAULT_FIELD_MATCH,
                                    new SimpleFragListBuilder(),
                                    new ScoreOrderFragmentsBuilder(new[] { "[b]" }, new[] { "[/b]" }));

            int i;
            for (i = (searchQuery.CurrentPage - 1) * PageSize; i < hits.Length; ++i)
            {
                var d = Searcher.Doc(hits[i].doc);
                var fq = fvh.GetFieldQuery(query);
                var fragment = fvh.GetBestFragment(fq, Searcher.GetIndexReader(),
                    hits[i].doc, "Content", 400);

                ret.SearchResults.Add(new SearchResultsViewModel.SearchResult
                {
                    Id = d.Get("Id"),
                    Title = d.Get("Title"),
                    Score = hits[i].score,
                    LuceneDocId = hits[i].doc,
                    Fragment = MvcHtmlString.Create(fragment.HtmlStripFragment()),
                });
            }
            return ret;
        }
Пример #3
0
        public static SearchResultsViewModel Search(SearchQuery searchQuery)
        {
            var ret = new SearchResultsViewModel
                      	{
                      		SearchResults = new List<SearchResultsViewModel.SearchResult>(PageSize), Query = searchQuery
                      	};

            // Parse query, possibly throwing a ParseException
            Query query;
            if (searchQuery.TitlesOnly) // we only need to query on one field
            {
                var qp = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "Title",
                                         new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29));
                query = qp.Parse(searchQuery.Query);
            }
            else // querying on both fields, Content and Title
            {
                query = MultiFieldQueryParser.Parse(Lucene.Net.Util.Version.LUCENE_29, searchQuery.Query,
                                                    SearchFields, SearchFlags,
                                                    new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29)
                                                    );
            }

            // Init the highlighter instance
            var fvh = new FastVectorHighlighter(FastVectorHighlighter.DEFAULT_PHRASE_HIGHLIGHT,
                                                FastVectorHighlighter.DEFAULT_FIELD_MATCH,
                                                new SimpleFragListBuilder(),
                                                new ScoreOrderFragmentsBuilder(new[] { "[b]" }, new[] { "[/b]" })
                                                );

            // Perform the actual search
            var tsdc = TopScoreDocCollector.create(PageSize * searchQuery.CurrentPage, true);
            Searcher.Search(query, tsdc);
            ret.TotalResults = tsdc.GetTotalHits();
            var hits = tsdc.TopDocs().ScoreDocs;

            int i;
            for (i = (searchQuery.CurrentPage - 1) * PageSize; i < hits.Length; ++i)
            {
                var d = Searcher.Doc(hits[i].doc);
                var fq = fvh.GetFieldQuery(query);
                var fragment = fvh.GetBestFragment(fq, Searcher.GetIndexReader(), hits[i].doc, "Content", 400);

                ret.SearchResults.Add(new SearchResultsViewModel.SearchResult
                {
                    Id = d.Get("Id"),
                    Title = d.Get("Title"),
                    Score = hits[i].score,
                    LuceneDocId = hits[i].doc,
                    Fragment = MvcHtmlString.Create(fragment.HtmlStripFragment()),
                });
            }
            return ret;
        }