public virtual async Task <SearchResult> SearchAsync(string term, int?filterByCategory = null, int languageId = -1, PostType?postType = null, SearchPlace searchPlace = SearchPlace.Anywhere, SearchResultSortType orderBy = SearchResultSortType.Score, int maxResult = 1000, bool exactSearch = false) { var result = new SearchResult(); term = term.Trim(); //replace multiple spaces with a single space RegexOptions options = RegexOptions.None; Regex regex = new Regex("[ ]{2,}", options); term = regex.Replace(term, " "); if (string.IsNullOrWhiteSpace(term)) { return(result); } var watch = new System.Diagnostics.Stopwatch(); watch.Start(); try { await Task.Run(() => { using (var directory = FSDirectory.Open(new DirectoryInfo(_indexFilesPath))) { using (var searcher = new IndexSearcher(directory, readOnly: true)) { var searchInFields = new List <string>(); if (searchPlace == SearchPlace.Anywhere) { searchInFields.AddRange(new string[] { "Title", "Description", "Keywords", "Tags" }); } else { if (searchPlace.HasFlagFast(SearchPlace.Title)) { searchInFields.Add("Title"); } if (searchPlace.HasFlagFast(SearchPlace.Description)) { searchInFields.Add("Description"); } if (searchPlace.HasFlagFast(SearchPlace.Keywords)) { searchInFields.Add("Keywords"); } if (searchPlace.HasFlagFast(SearchPlace.Tags)) { searchInFields.Add("Tags"); } } BooleanFilter filter = null; if (languageId > -1 || filterByCategory != null || postType != null) { filter = new BooleanFilter(); if (languageId > -1) { filter.Add(new FilterClause( new QueryWrapperFilter(new TermQuery(new Term("LanguageId", languageId.ToString()))), Occur.MUST)); } if (filterByCategory != null) { filter.Add(new FilterClause( new QueryWrapperFilter(new TermQuery(new Term("Categories", filterByCategory.Value.ToString()))), Occur.MUST)); } if (postType != null) { filter.Add(new FilterClause( new QueryWrapperFilter(new TermQuery(new Term("PostType", postType.Value.ToString()))), Occur.MUST)); } } var currentSettings = _settingService.LoadSetting <SiteSettings>(); if (!currentSettings.EnableBlog) { //Filter Blog Posts if Blog is disabled if (filter == null) { filter = new BooleanFilter(); } filter.Add(new FilterClause( new QueryWrapperFilter(new TermQuery(new Term("PostType", PostType.BlogPost.ToString()))), Occur.MUST_NOT)); } Sort sort = new Sort(SortField.FIELD_SCORE); switch (orderBy) { case SearchResultSortType.NumberOfVisits: sort = new Sort(new SortField("NumberOfVisit", SortField.INT, true)); break; case SearchResultSortType.PublishDate: sort = new Sort(new SortField("PublishDate", SortField.LONG, true)); break; case SearchResultSortType.LastUpDate: sort = new Sort(new SortField("LastUpDate", SortField.LONG, true)); break; } var analyzer = new StandardAnalyzer(Version); var parser = new MultiFieldQueryParser(Version, searchInFields.ToArray(), analyzer); QueryScorer scorer = null; var hits = new List <ScoreDoc>(); Query query = null; if (exactSearch) { query = ParseQuery(term, parser); hits.AddRange(searcher.Search(query, filter, maxResult, sort).ScoreDocs); } else { query = ParseQuery($"(\"{term}\")", parser); hits.AddRange(searcher.Search(query, filter, maxResult, sort).ScoreDocs); query = ParseQuery($"({term.Replace(" ", "*")})", parser); hits.AddRange(searcher.Search(query, filter, maxResult, sort).ScoreDocs); query = ParseQuery($"(+{term.Trim().Replace(" ", " +")})", parser); hits.AddRange(searcher.Search(query, filter, maxResult, sort).ScoreDocs); query = ParseQuery(term, parser); hits.AddRange(searcher.Search(query, filter, maxResult, sort).ScoreDocs); } scorer = new QueryScorer(query); if (hits.Count == 0) { term = SearchByPartialWords(term); query = ParseQuery(term, parser); scorer = new QueryScorer(query); hits.AddRange(searcher.Search(query, filter, maxResult, sort).ScoreDocs); } var formatter = new SimpleHTMLFormatter( "<span class='badge badge-warning'>", "</span>"); var fragmenter = new SimpleFragmenter(300); var highlighter = new Highlighter(formatter, scorer) { TextFragmenter = fragmenter }; foreach (var scoreDoc in hits) { var doc = searcher.Doc(scoreDoc.Doc); result.Documents.Add(new SearchResultDocument() { DocumentId = int.Parse(doc.Get("ID")), LanguageId = int.Parse(doc.Get("LanguageId")), LanguageIsoCode = doc.Get("LanguageCode"), Score = scoreDoc.Score, DocumentTitle = GetHighlight("Title", highlighter, analyzer, doc.Get("Title"), false), DocumentBody = GetHighlight("Description", highlighter, analyzer, doc.Get("Description"), true), DocumentKeywords = doc.Get("Keywords"), DocumentTags = doc.Get("Tags"), }); } result.Documents = result.Documents.DistinctBy(p => new { p.DocumentId }) .ToList(); analyzer.Close(); //SuggestSimilar using (var spellDirectory = FSDirectory.Open(new DirectoryInfo(_spellFilesPath))) { using (var spellChecker = new SpellChecker.Net.Search.Spell.SpellChecker(spellDirectory)) { result.SuggestSimilar.AddRange(spellChecker.SuggestSimilar(term, 10, null, null, true)); } } } } }); } catch (Exception ex) { result.Error = ex; result.HasError = true; } watch.Stop(); result.ElapsedMilliseconds = watch.ElapsedMilliseconds; _eventPublisher.Publish(new SearchEvent(term, filterByCategory, languageId, postType, searchPlace, maxResult, result)); return(result); }
public virtual SearchResult MoreLikeThis(int postId, int?filterByCategory = null, int languageId = -1, PostType?postType = null, SearchPlace searchPlace = SearchPlace.Title | SearchPlace.Description, int maxResult = 5, SearchResultSortType orderBy = SearchResultSortType.Score) { var result = new SearchResult(); var watch = new System.Diagnostics.Stopwatch(); watch.Start(); try { using (var directory = FSDirectory.Open(new DirectoryInfo(_indexFilesPath))) { using (var searcher = new IndexSearcher(directory, readOnly: true)) { var docNumber = GetLuceneDocNumber(postId, searcher); if (docNumber == -1) { return(result); } var searchInFields = new List <string>(); if (searchPlace == SearchPlace.Anywhere) { searchInFields.AddRange(new string[] { "Title", "Description", "Keywords", "Tags" }); } else { if (searchPlace.HasFlagFast(SearchPlace.Title)) { searchInFields.Add("Title"); } if (searchPlace.HasFlagFast(SearchPlace.Description)) { searchInFields.Add("Description"); } if (searchPlace.HasFlagFast(SearchPlace.Keywords)) { searchInFields.Add("Keywords"); } if (searchPlace.HasFlagFast(SearchPlace.Tags)) { searchInFields.Add("Tags"); } } var analyzer = new StandardAnalyzer(Version); var moreLikeThis = new MoreLikeThis(searcher.IndexReader) { Analyzer = analyzer }; moreLikeThis.SetFieldNames(searchInFields.ToArray()); moreLikeThis.MinDocFreq = 1; moreLikeThis.MinTermFreq = 1; moreLikeThis.Boost = true; var query = moreLikeThis.Like(docNumber); var filter = new BooleanFilter(); filter.Add(new FilterClause( new QueryWrapperFilter(new TermQuery(new Term("ID", postId.ToString()))), Occur.MUST_NOT)); if (languageId > -1) { filter.Add(new FilterClause( new QueryWrapperFilter(new TermQuery(new Term("LanguageId", languageId.ToString()))), Occur.MUST)); } if (filterByCategory != null) { filter.Add(new FilterClause( new QueryWrapperFilter(new TermQuery(new Term("Categories", filterByCategory.Value.ToString()))), Occur.MUST)); } if (postType != null) { filter.Add(new FilterClause( new QueryWrapperFilter(new TermQuery(new Term("PostType", postType.Value.ToString()))), Occur.MUST)); } Sort sort = new Sort(SortField.FIELD_SCORE); switch (orderBy) { case SearchResultSortType.NumberOfVisits: sort = new Sort(new SortField("NumberOfVisit", SortField.INT, true)); break; case SearchResultSortType.PublishDate: sort = new Sort(new SortField("PublishDate", SortField.LONG, true)); break; case SearchResultSortType.LastUpDate: sort = new Sort(new SortField("LastUpDate", SortField.LONG, true)); break; } var hits = searcher.Search(query, filter, maxResult, sort).ScoreDocs; foreach (var scoreDoc in hits) { var doc = searcher.Doc(scoreDoc.Doc); result.Documents.Add(new SearchResultDocument() { DocumentId = int.Parse(doc.Get("ID")), LanguageId = int.Parse(doc.Get("LanguageId")), LanguageIsoCode = doc.Get("LanguageCode"), Score = scoreDoc.Score, DocumentTitle = doc.Get("Title"), DocumentBody = doc.Get("Description"), DocumentKeywords = doc.Get("Keywords"), DocumentTags = doc.Get("Tags"), }); } result.Documents = result.Documents.DistinctBy(p => new { p.DocumentId }) .ToList(); analyzer.Close(); } } } catch (Exception ex) { result.Error = ex; result.HasError = true; } watch.Stop(); result.ElapsedMilliseconds = watch.ElapsedMilliseconds; return(result); }