/// <summary> /// Searches for and displays results. /// </summary> /// <param name="search">The text to search for. Supports file title and contents.</param> /// <param name="writeToConsole">Whether or not to write search status to console (errors still report).</param> public Task <List <string> > SearchFiles(string search, bool writeToConsole = true) { SearchText = search; return(Task.Run(() => { var matches = new List <string>(); if (!IndexDirectoryExists() && !DirectoryReader.IndexExists(fSDirectory)) { GeneralHelper.WriteToConsole($"No index available! Please unpack game assets and generate an index.\n"); return matches; } try { using (Analyzer analyzer = new CustomAnalyzer()) using (IndexReader reader = DirectoryReader.Open(fSDirectory)) { IndexSearcher searcher = new IndexSearcher(reader); MultiFieldQueryParser queryParser = new MultiFieldQueryParser(LuceneVersion.LUCENE_48, new[] { "title", "body" }, analyzer) { AllowLeadingWildcard = true }; Query searchTermQuery = queryParser.Parse('*' + QueryParser.Escape(search.Trim()) + '*'); BooleanQuery aggregateQuery = new BooleanQuery() { { searchTermQuery, Occur.MUST } }; if (reader.MaxDoc != 0) { var start = DateTime.Now; if (writeToConsole) { GeneralHelper.WriteToConsole("Search started.\n"); } // perform search TopDocs topDocs = searcher.Search(aggregateQuery, reader.MaxDoc); if (writeToConsole) { GeneralHelper.WriteToConsole($"Search returned {topDocs.ScoreDocs.Length} results in {TimeSpan.FromTicks(DateTime.Now.Subtract(start).Ticks).TotalMilliseconds} ms\n"); } // display results foreach (ScoreDoc scoreDoc in topDocs.ScoreDocs) { float score = scoreDoc.Score; int docId = scoreDoc.Doc; Document doc = searcher.Doc(docId); matches.Add(doc.Get("path")); } } else { GeneralHelper.WriteToConsole("No documents available. Please generate the index again.\n"); } } } catch { // Checking if the index is corrupt is slower than just letting it fail GeneralHelper.WriteToConsole($"Available index is corrupt. Please rerun the indexer to create a new one.\n"); } return matches.OrderBy(m => m).ToList(); })); }
private bool BuildQuery(StringBuilder sb, string query, string searchFrom, List <string> fields, string type) { //build a lucene query: // the nodeName will be boosted 10x without wildcards // then nodeName will be matched normally with wildcards // the rest will be normal without wildcards var allLangs = _languageService.GetAllLanguages().Select(x => x.IsoCode.ToLowerInvariant()).ToList(); // the chars [*-_] in the query will mess everything up so let's remove those query = Regex.Replace(query, "[\\*\\-_]", ""); //check if text is surrounded by single or double quotes, if so, then exact match var surroundedByQuotes = Regex.IsMatch(query, "^\".*?\"$") || Regex.IsMatch(query, "^\'.*?\'$"); if (surroundedByQuotes) { //strip quotes, escape string, the replace again query = query.Trim(Constants.CharArrays.DoubleQuoteSingleQuote); query = QueryParser.Escape(query); //nothing to search if (searchFrom.IsNullOrWhiteSpace() && query.IsNullOrWhiteSpace()) { return(false); } //update the query with the query term if (query.IsNullOrWhiteSpace() == false) { //add back the surrounding quotes query = string.Format("{0}{1}{0}", "\"", query); sb.Append("+("); AppendNodeNamePhraseWithBoost(sb, query, allLangs); foreach (var f in fields) { //additional fields normally sb.Append(f); sb.Append(": ("); sb.Append(query); sb.Append(") "); } sb.Append(") "); } } else { var trimmed = query.Trim(Constants.CharArrays.DoubleQuoteSingleQuote); //nothing to search if (searchFrom.IsNullOrWhiteSpace() && trimmed.IsNullOrWhiteSpace()) { return(false); } //update the query with the query term if (trimmed.IsNullOrWhiteSpace() == false) { query = QueryParser.Escape(query); var querywords = query.Split(Constants.CharArrays.Space, StringSplitOptions.RemoveEmptyEntries); sb.Append("+("); AppendNodeNameExactWithBoost(sb, query, allLangs); AppendNodeNameWithWildcards(sb, querywords, allLangs); foreach (var f in fields) { var queryWordsReplaced = new string[querywords.Length]; // when searching file names containing hyphens we need to replace the hyphens with spaces if (f.Equals(UmbracoExamineFieldNames.UmbracoFileFieldName)) { for (var index = 0; index < querywords.Length; index++) { queryWordsReplaced[index] = querywords[index].Replace("\\-", " ").Replace("_", " ").Trim(" "); } } else { queryWordsReplaced = querywords; } //additional fields normally sb.Append(f); sb.Append(":"); sb.Append("("); foreach (var w in queryWordsReplaced) { sb.Append(w.ToLower()); sb.Append("* "); } sb.Append(")"); sb.Append(" "); } sb.Append(") "); } } //must match index type sb.Append("+__IndexType:"); sb.Append(type); return(true); }
public ISearchBuilder WithinRange(string field, string min, string max, bool includeMin = true, bool includeMax = true) { CreatePendingClause(); _query = new TermRangeQuery(field, min != null ? QueryParser.Escape(min) : null, max != null ? QueryParser.Escape(max) : null, includeMin, includeMax); return(this); }
public static string Escape(string query) { return(QueryParser.Escape(query)); }
public async Task <IActionResult> Search(SearchIndexViewModel viewModel, PagerSlimParameters pagerParameters) { var permissionsProvider = _permissionProviders.FirstOrDefault(x => x.GetType().FullName == "OrchardCore.Lucene.Permissions"); var permissions = await permissionsProvider.GetPermissionsAsync(); var siteSettings = await _siteService.GetSiteSettingsAsync(); var searchSettings = siteSettings.As <LuceneSettings>(); if (permissions.FirstOrDefault(x => x.Name == "QueryLucene" + searchSettings.SearchIndex + "Index") != null) { if (!await _authorizationService.AuthorizeAsync(User, permissions.FirstOrDefault(x => x.Name == "QueryLucene" + searchSettings.SearchIndex + "Index"))) { return(this.ChallengeOrForbid()); } } else { _logger.LogInformation("Couldn't execute search. The search index doesn't exist."); return(BadRequest("Search is not configured.")); } if (searchSettings.SearchIndex != null && !_luceneIndexProvider.Exists(searchSettings.SearchIndex)) { _logger.LogInformation("Couldn't execute search. The search index doesn't exist."); return(BadRequest("Search is not configured.")); } var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync(); if (luceneSettings == null || luceneSettings?.DefaultSearchFields == null) { _logger.LogInformation("Couldn't execute search. No Lucene settings was defined."); return(BadRequest("Search is not configured.")); } var luceneIndexSettings = await _luceneIndexSettingsService.GetSettingsAsync(searchSettings.SearchIndex); if (luceneIndexSettings == null) { _logger.LogInformation($"Couldn't execute search. No Lucene index settings was defined for ({searchSettings.SearchIndex}) index."); return(BadRequest($"Search index ({searchSettings.SearchIndex}) is not configured.")); } if (string.IsNullOrWhiteSpace(viewModel.Terms)) { return(View(new SearchIndexViewModel { SearchForm = new SearchFormViewModel("Search__Form") { }, })); } var pager = new PagerSlim(pagerParameters, siteSettings.PageSize); // We Query Lucene index var analyzer = _luceneAnalyzerManager.CreateAnalyzer(await _luceneIndexSettingsService.GetIndexAnalyzerAsync(luceneIndexSettings.IndexName)); var queryParser = new MultiFieldQueryParser(LuceneSettings.DefaultVersion, luceneSettings.DefaultSearchFields, analyzer); var query = queryParser.Parse(QueryParser.Escape(viewModel.Terms)); // Fetch one more result than PageSize to generate "More" links var start = 0; var end = pager.PageSize + 1; if (pagerParameters.Before != null) { start = Convert.ToInt32(pagerParameters.Before) - pager.PageSize - 1; end = Convert.ToInt32(pagerParameters.Before); } else if (pagerParameters.After != null) { start = Convert.ToInt32(pagerParameters.After); end = Convert.ToInt32(pagerParameters.After) + pager.PageSize + 1; } var contentItemIds = await _searchQueryService.ExecuteQueryAsync(query, searchSettings.SearchIndex, start, end); // We Query database to retrieve content items. IQuery <ContentItem> queryDb; if (luceneIndexSettings.IndexLatest) { queryDb = _session.Query <ContentItem, ContentItemIndex>() .Where(x => x.ContentItemId.IsIn(contentItemIds) && x.Latest == true) .Take(pager.PageSize + 1); } else { queryDb = _session.Query <ContentItem, ContentItemIndex>() .Where(x => x.ContentItemId.IsIn(contentItemIds) && x.Published == true) .Take(pager.PageSize + 1); } var containedItems = await queryDb.ListAsync(); // We set the PagerSlim before and after links if (pagerParameters.After != null || pagerParameters.Before != null) { if (start + 1 > 1) { pager.Before = (start + 1).ToString(); } else { pager.Before = null; } } if (containedItems.Count() == pager.PageSize + 1) { pager.After = (end - 1).ToString(); } else { pager.After = null; } var model = new SearchIndexViewModel { Terms = viewModel.Terms, SearchForm = new SearchFormViewModel("Search__Form") { Terms = viewModel.Terms }, SearchResults = new SearchResultsViewModel("Search__Results") { ContentItems = containedItems.Take(pager.PageSize) }, Pager = (await New.PagerSlim(pager)).UrlParams(new Dictionary <string, string>() { { "Terms", viewModel.Terms } }) }; return(View(model)); }
private static string Escape(string term) { return(QueryParser.Escape(term).ToLowerInvariant()); }
/// <summary> /// Return the quoted and escaped search term as a list /// </summary> /// <param name="searchTerm"></param> /// <returns></returns> public static List <string> GetSearchTermQuoted(string searchTerm) { return(new List <string> { '"' + QueryParser.Escape(searchTerm) + '"' }); }
private void AddRulles(BooleanQuery q, List <FilterRule> filterRules, Occur cond) { foreach (var rule in filterRules) { string fieldName = rule.Field; if (fieldName == "id") { fieldName = "$id"; } if (fieldName == "userid") { fieldName = "$userid"; } if (rule.FieldOperator == OperatorEnum.EQUAL) { if (rule.FieldType == FieldTypeEnum.BOOLEAN) { int ival = rule.Value.AsBoolean ? 1 : 0; q.Add(NumericRangeQuery.NewIntRange(fieldName, ival, ival, true, true), cond); } else if (rule.FieldType == FieldTypeEnum.FLOAT) { float fval = rule.Value.AsFloat; q.Add(NumericRangeQuery.NewFloatRange(fieldName, fval, fval, true, true), cond); } else if (rule.FieldType == FieldTypeEnum.STRING || rule.FieldType == FieldTypeEnum.TEXT || rule.FieldType == FieldTypeEnum.HTML) { q.Add(LuceneController.ParseQuery(rule.Value.AsString + "*", fieldName), cond); } else { string searchstring = QueryParser.Escape(rule.Value.AsString); q.Add(new TermQuery(new Term(fieldName, searchstring)), cond); } } else if (rule.FieldOperator == OperatorEnum.NOT_EQUAL) { q.Add(new TermQuery(new Term(fieldName, rule.Value.AsString)), Occur.MUST_NOT); } else if (rule.FieldOperator == OperatorEnum.START_WITH) { if (rule.FieldType == FieldTypeEnum.STRING || rule.FieldType == FieldTypeEnum.TEXT || rule.FieldType == FieldTypeEnum.HTML) { q.Add(LuceneController.ParseQuery(rule.Value.AsString + "*", fieldName), cond); } else { q.Add(new WildcardQuery(new Term(fieldName, rule.Value.AsString + "*")), cond); } } else if (rule.FieldOperator == OperatorEnum.IN) { BooleanQuery arrQ = new BooleanQuery(); foreach (var arrItem in rule.MultiValue) { arrQ.Add(new TermQuery(new Term(fieldName, QueryParser.Escape(arrItem.AsString))), Occur.SHOULD); // OR /* * var phraseQ = new PhraseQuery(); * phraseQ.Add(new Term(fieldName, arrItem.AsString)); * arrQ.Add(phraseQ, Occur.SHOULD); // OR */ } q.Add(arrQ, cond); } else if (rule.FieldOperator == OperatorEnum.BETWEEN) { if (rule.FieldType == FieldTypeEnum.DATETIME) { var startDate = rule.LowerValue.AsDateTime; var endDate = rule.UpperValue.AsDateTime; q.Add(NumericRangeQuery.NewLongRange(fieldName, startDate.Ticks, endDate.Ticks, true, true), cond); } } else if (rule.FieldOperator == OperatorEnum.GREATER_THEN_OR_EQUALS) { DateTime startDate = rule.Value.AsDateTime; DateTime endDate = DateTime.MaxValue; q.Add(NumericRangeQuery.NewLongRange(fieldName, startDate.Ticks, endDate.Ticks, true, true), cond); } else if (rule.FieldOperator == OperatorEnum.LESS_THEN_OR_EQUALS) { if (rule.FieldType == FieldTypeEnum.DATETIME) { DateTime startDate = DateTime.MinValue; DateTime endDate = rule.Value.AsDateTime; q.Add(NumericRangeQuery.NewLongRange(fieldName, startDate.Ticks, endDate.Ticks, true, true), cond); } } else if (rule.FieldOperator == OperatorEnum.GREATER_THEN) { } else if (rule.FieldOperator == OperatorEnum.LESS_THEN) { } } }
public ISearchBuilder WithinRange(string field, string min, string max) { CreatePendingClause(); _query = new TermRangeQuery(field, QueryParser.Escape(min.ToLower()), QueryParser.Escape(max.ToLower()), true, true); return(this); }
private static Results <T> GetResults <T>(string query, string type) { string didYouMean; TopDocs topDocs; query = query.Trim().ToLower().Replace("'", "").Replace("-", " "); Analyzer analyzer = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_29); Directory directory = FSDirectory.Open(new System.IO.DirectoryInfo(IndexDirectory + type)); string[] fields = new string[] { "Search" }; MultiFieldQueryParser parser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_29, fields, analyzer); BooleanQuery booleanQuery = new BooleanQuery(); string[] searchWords = query.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries); string[] didYouMeans = new string[searchWords.Length]; didYouMean = string.Empty; foreach (string word in searchWords) { if (word != "&") { booleanQuery.Add(parser.Parse(QueryParser.Escape(word).Replace("~", "") + "~"), Occur.MUST); } } IndexReader reader = IndexReader.Open(directory, true); Searcher searcher = new IndexSearcher(reader); topDocs = searcher.Search(booleanQuery, reader.MaxDoc); ScoreDoc[] scoreDocs = topDocs.ScoreDocs; bool exactMatch = false; List <string> results = new List <string>(); for (int i = 0; i < scoreDocs.Length; i++) { int doc = scoreDocs[i].Doc; float score = scoreDocs[i].Score; DateTime date = DateTime.Now; Document document = searcher.Doc(doc); results.Add(document.Get("Id")); if (!exactMatch) { string input = document.Get("Search").ToLower(); bool match = true; for (int j = 0; j < searchWords.Length; j++) { string word = searchWords[j]; if (Regex.IsMatch(input, @"(^|\s|\b)" + Regex.Escape(word) + @"(\b|\s|$)", RegexOptions.IgnoreCase)) { if (didYouMeans[j] != word) { didYouMeans[j] = word; } } else { match = false; if (string.IsNullOrEmpty(didYouMeans[j])) { didYouMeans[j] = SuggestSimilar(word, type); } } } exactMatch = match; } } query = string.Join(" ", searchWords); if (!exactMatch) { didYouMean = string.Join(" ", didYouMeans); } query = string.Join(" ", searchWords); if (!exactMatch) { didYouMean = string.Join(" ", didYouMeans); } Results <T> model = new Results <T> { DidYouMean = didYouMean, Ids = results.ToList(), TotalHits = topDocs.TotalHits }; reader.Dispose(); searcher.Dispose(); directory.Dispose(); analyzer.Dispose(); return(model); }
public static string Escape(this string s) { return(QueryParser.Escape(s)); }
/// <summary> /// Searches the lucene index with the search text. /// </summary> /// <param name="searchText">The text to search with.</param> /// <remarks>Syntax reference: http://lucene.apache.org/java/2_3_2/queryparsersyntax.html#Wildcard</remarks> /// <exception cref="SearchException">An error occured searching the lucene.net index.</exception> public virtual IEnumerable <SearchResultViewModel> Search(string searchText) { // This check is for the benefit of the CI builds if (!Directory.Exists(IndexPath)) { CreateIndex(); } List <SearchResultViewModel> list = new List <SearchResultViewModel>(); if (string.IsNullOrWhiteSpace(searchText)) { return(list); } StandardAnalyzer analyzer = new StandardAnalyzer(LUCENEVERSION); MultiFieldQueryParser parser = new MultiFieldQueryParser(LuceneVersion.LUCENE_29, new string[] { "content", "title" }, analyzer); Query query = null; try { query = parser.Parse(searchText); } catch (Lucene.Net.QueryParsers.ParseException) { // Catch syntax errors in the search and remove them. searchText = QueryParser.Escape(searchText); query = parser.Parse(searchText); } if (query != null) { try { using (IndexSearcher searcher = new IndexSearcher(FSDirectory.Open(new DirectoryInfo(IndexPath)), true)) { TopDocs topDocs = searcher.Search(query, 1000); foreach (ScoreDoc scoreDoc in topDocs.ScoreDocs) { Document document = searcher.Doc(scoreDoc.Doc); list.Add(new SearchResultViewModel(document, scoreDoc)); } } } catch (FileNotFoundException) { // For 1.7's change to the Lucene search path. CreateIndex(); } catch (Exception ex) { throw new SearchException(ex, "An error occured while searching the index, try rebuilding the search index via the admin tools to fix this."); } } if (!_context.IsAdmin) { List <int> toBeRemove = new List <int>(); foreach (var page in list) { bool restrict_page = false; bool user_have_access = false; foreach (var tag1 in page.Tags.Split(' ')) { if (tag1.StartsWith("#")) { restrict_page = true; Database.User user = _UserService.GetUserById(new Guid(_context.CurrentUser)); foreach (var permission in user.Permission.Split(',')) { if (permission.ToLower() == tag1.Replace("#", "").ToLower()) { user_have_access = true; break; } } /* * if (tag1.Replace("#", "").ToLower() == _context.CurrentUsername.ToLower()) * { * user_have_access = true; * } */ } } if (restrict_page && !user_have_access) { toBeRemove.Add(page.Id); } } foreach (int i in toBeRemove) { list = list.Where(p => p.Id != i).ToList(); } } return(list); }
/// <summary> /// Constracts a boolean query from a searchterm dictionary /// </summary> /// <param name="SearchTermFields"></param> /// <returns></returns> private QueryDesriptor SearchTermQuery(IEnumerable <SearchTerm> SearchTermFields) { QueryDesriptor descriptor = new QueryDesriptor(); BooleanQuery query = new BooleanQuery(); Query areaQuery = null; foreach (SearchTerm entry in SearchTermFields) { if (entry == null) { continue; } if (entry.InArea != null && areaQuery == null) { IPoint p = SpatialContext.MakePoint(entry.InArea.Center.Latitude, entry.InArea.Center.Longitude); var circle = SpatialContext.MakeCircle(entry.InArea.Center.Latitude, entry.InArea.Center.Longitude, DistanceUtils.Dist2Degrees(entry.InArea.Radius, DistanceUtils.EARTH_EQUATORIAL_RADIUS_KM)); descriptor.SpatialArguments = new SpatialArgs(SpatialOperation.IsWithin, circle); descriptor.Filter = spatialStrategy.MakeFilter(descriptor.SpatialArguments); descriptor.InArea = true; areaQuery = ((PointVectorStrategy)spatialStrategy).MakeQueryDistanceScore(descriptor.SpatialArguments); } else if (entry.SearchingOption == SearchFieldOption.INTRANGE) { NumericRangeQuery <int> nq = NumericRangeQuery.NewInt32Range(entry.Field, entry.FromAsInt, entry.ToAsInt, true, true); query.Add(nq, entry.TermOccur); } else if (entry.SearchingOption == SearchFieldOption.DOUBLERANGE || entry.SearchingOption == SearchFieldOption.DECIMALRANGE) { NumericRangeQuery <double> nq = NumericRangeQuery.NewDoubleRange(entry.Field, entry.FromAsDouble, entry.ToAsDouble, true, true); query.Add(nq, entry.TermOccur); } //else if (entry.SearchingOption == SearchFieldOption.DECIMALRANGE) //{ // TermRangeQuery nq = TermRangeQuery.NewStringRange(entry.Field, entry.FromAsDecimal, entry.ToAsDecimal, true, true); // query.Add(nq, entry.TermOccur); //} else if (entry.SearchingOption == SearchFieldOption.LIKE) { QueryParser parser = new QueryParser(wings.IndexVersion, entry.Field, Analyzer); Query pquery = WildparseQuery(wings.Transformation.Transform(entry.Term), parser); query.Add(pquery, entry.TermOccur); } else if (entry.SearchingOption == SearchFieldOption.EXACT) { var exactQuery = new TermQuery(new Term(entry.Field, QueryParser.Escape(entry.Term.Trim()))); query.Add(exactQuery, entry.TermOccur); } else if (entry.SearchingOption == SearchFieldOption.FUZZY) { QueryParser parser = new QueryParser(wings.IndexVersion, entry.Field, Analyzer); Query pquery = FuzzyparseQuery(wings.Transformation.Transform(entry.Term), parser); query.Add(pquery, entry.TermOccur); } else { QueryParser parser = new QueryParser(wings.IndexVersion, entry.Field, Analyzer); Query pquery = ParseQuery(entry.Term, parser); query.Add(pquery, entry.TermOccur); } } if (areaQuery != null) { BooleanQuery areaQueries = new BooleanQuery { { query, Occur.MUST }, { areaQuery, Occur.MUST } }; descriptor.Query = areaQueries; } else { descriptor.Query = query; } return(descriptor); }
public SearchResults Search(SearchRequest request) { if (!OpenReader()) { return(new SearchResults { Query = request.Query }); } if (!reader.IsCurrent()) { reader = reader.Reopen(); } var take = request.Take > 0 ? request.Take : SearchModuleConstants.DefaultSearchResultsCount; var skip = request.Skip > 0 ? request.Skip : 0; var result = new List <SearchResultItem>(); var searcher = new IndexSearcher(reader); TopScoreDocCollector collector = TopScoreDocCollector.Create(take + skip, true); var searchQuery = request.Query; Query query; try { query = parser.Parse(searchQuery); } catch (ParseException) { try { searchQuery = QueryParser.Escape(searchQuery); query = parser.Parse(searchQuery); } catch (ParseException exc) { throw new ValidationException(() => exc.Message, exc.Message, exc); } } if (!RetrieveUnpublishedPages()) { // Exclude unpublished pages var isPublishedQuery = new TermQuery(new Term(LuceneIndexDocumentKeys.IsPublished, "true")); Filter isPublishedFilter = new QueryWrapperFilter(isPublishedQuery); searcher.Search(query, isPublishedFilter, collector); } else { // Search within all the pages searcher.Search(query, collector); } ScoreDoc[] hits = collector.TopDocs(skip, take).ScoreDocs; for (int i = 0; i < hits.Length; i++) { int docId = hits[i].Doc; Document d = searcher.Doc(docId); result.Add(new SearchResultItem { FormattedUrl = d.Get(LuceneIndexDocumentKeys.Path), Link = d.Get(LuceneIndexDocumentKeys.Path), Title = d.Get(LuceneIndexDocumentKeys.Title), Snippet = GetSnippet(d.Get(LuceneIndexDocumentKeys.Content), request.Query) }); } CheckAvailability(result); return(new SearchResults { Items = result, Query = request.Query, TotalResults = collector.TotalHits }); }
/// <summary> /// Return the escaped search term as a list /// </summary> /// <param name="searchTerm"></param> /// <returns></returns> public static List <string> GetSearchTermEscaped(string searchTerm) { return(new List <string> { QueryParser.Escape(searchTerm) }); }
private ILuceneSearchResultCollection PerformSearch(SearchOptions options, bool safeSearch) { // Results collection ILuceneSearchResultCollection results = new LuceneSearchResultCollection(); using (var reader = IndexReader.Open(directory, true)) using (var searcher = new IndexSearcher(reader)) { Query query; // calculate the scores - this has a cpu hit!!! searcher.SetDefaultFieldSortScoring(true, true); // Escape our search if we're performing a safe search if (safeSearch == true) { options.SearchText = QueryParser.Escape(options.SearchText); } if (options.Fields.Count() == 1) { // Single field search QueryParser queryParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, options.Fields[0], analyzer); query = queryParser.Parse(options.SearchText); } else { // Parse the boosts against the fields // Multifield search MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(Lucene.Net.Util.Version.LUCENE_30, options.Fields.ToArray(), analyzer, options.Boosts); query = multiFieldQueryParser.Parse(options.SearchText); } List <SortField> sortFields = new List <SortField>(); sortFields.Add(SortField.FIELD_SCORE); // if we have any sort fields then add them foreach (var sortField in options.OrderBy) { sortFields.Add(new SortField(sortField, SortField.STRING)); } // create our sort Sort sort = new Sort(sortFields.ToArray()); ScoreDoc[] matches = searcher.Search(query, null, options.MaximumNumberOfHits, sort).ScoreDocs; results.TotalHits = matches.Count(); // perform skip and take if needed if (options.Skip.HasValue) { matches = matches.Skip(options.Skip.Value).ToArray(); } if (options.Take.HasValue) { matches = matches.Take(options.Take.Value).ToArray(); } // create a list of documents from the results foreach (var match in matches) { var id = match.Doc; var doc = searcher.Doc(id); // filter out unwanted documents if a type has been set if (options.Type != null) { var t = doc.Get("Type"); if (options.Type.AssemblyQualifiedName == t) { results.Results.Add(new LuceneSearchResult() { Score = match.Score, Document = doc }); } } else { results.Results.Add(new LuceneSearchResult() { Score = match.Score, Document = doc }); } } } return(results); }
public async Task <IActionResult> Index(string id, string q, PagerParameters pagerParameters) { var siteSettings = await _siteService.GetSiteSettingsAsync(); var pager = new Pager(pagerParameters, siteSettings.PageSize); var indexName = "Search"; if (!string.IsNullOrWhiteSpace(id)) { indexName = id; } if (!_luceneIndexProvider.Exists(indexName)) { return(NotFound()); } if (string.IsNullOrWhiteSpace(q)) { return(View(new SearchIndexViewModel { Pager = pager, IndexName = id, ContentItems = Enumerable.Empty <ContentItem>() })); } var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync(); if (luceneSettings == null || luceneSettings?.DefaultSearchFields == null) { Logger.LogInformation("Couldn't execute search. No Lucene settings was defined."); return(View(new SearchIndexViewModel { HasMoreResults = false, Query = q, Pager = pager, IndexName = id, ContentItems = Enumerable.Empty <ContentItem>() })); } var queryParser = new MultiFieldQueryParser(LuceneSettings.DefaultVersion, luceneSettings.DefaultSearchFields, new StandardAnalyzer(LuceneSettings.DefaultVersion)); var query = queryParser.Parse(QueryParser.Escape(q)); int start = pager.GetStartIndex(), size = pager.PageSize, end = size + 1;// Fetch one more result than PageSize to generate "More" links var contentItemIds = await _searchQueryService.ExecuteQueryAsync(query, indexName, start, end); var contentItems = new List <ContentItem>(); foreach (var contentItemId in contentItemIds.Take(size)) { var contentItem = await _contentManager.GetAsync(contentItemId); if (contentItem != null) { contentItems.Add(contentItem); } } var model = new SearchIndexViewModel { HasMoreResults = contentItemIds.Count > size, Query = q, Pager = pager, IndexName = id, ContentItems = contentItems }; return(View(model)); }
private Result GetSearchResults(string searchQuery, string[] searchFields, string sortField, bool sortDescending, int count, int skip, ApprovalState approvalState = ApprovalState.Any) { var reader = GetIndexReader(); var searcher = GetIndexSearcher(reader); string sortFieldName; if (string.IsNullOrWhiteSpace(sortField)) { sortField = sortFieldName = CreatedField; sortDescending = true; } else if (sortField == CreatedField) { sortFieldName = CreatedField; } else { sortFieldName = FieldNameForSorting(sortField); } Query query; if (string.IsNullOrWhiteSpace(searchQuery) == false && searchFields != null && searchFields.Any()) { //searchQuery = searchQuery.Replace("*", "").Replace(" ", "* ") + "*"; if (searchFields.Count() > 1) { var parser = new MultiFieldQueryParser(Version.LUCENE_29, searchFields, GetAnalyzer()); parser.SetDefaultOperator(QueryParser.Operator.AND); Log.Info("searchQuery =" + searchQuery, null); try { query = parser.Parse(searchQuery.Trim()); } catch (ParseException ex) { Log.Error(ex, ex.Message, null); query = parser.Parse(QueryParser.Escape(searchQuery.Trim())); } } else { query = new QueryParser(Version.LUCENE_29, searchFields.FirstOrDefault(), GetAnalyzer()).Parse(searchQuery); } } else { query = approvalState == ApprovalState.Any ? new MatchAllDocsQuery() : (Query) new TermQuery(new Term(ApprovalField, approvalState.ToString())); } var docs = searcher.Search( query, null, reader.MaxDoc(), new Sort(new SortField(sortFieldName, SortField.STRING, sortDescending)) ); var scoreDocs = docs.ScoreDocs; var rows = new List <Row>(); for (var i = skip; i < (skip + count) && i < scoreDocs.Length; i++) { if (reader.IsDeleted(scoreDocs[i].doc)) { continue; } var doc = searcher.Doc(scoreDocs[i].doc); var row = ParseRow(doc); rows.Add(row); } searcher.Close(); reader.Close(); return(new Result(scoreDocs.Count(), rows, sortField, sortDescending)); }
/// <summary> /// Adds the given JToken to the specified Document. /// </summary> /// <param name="doc"> /// The Document to add to. /// </param> /// <param name="prefix"> /// The prefix to use for field names. /// </param> /// <param name="token"> /// The JToken to add. /// </param> /// <param name="fieldconfig"></param> private static void Add(Document doc, string prefix, JToken token, FieldConfig fieldconfig) { if (token is JObject) { AddProperties(doc, prefix, token as JObject, fieldconfig); } else if (token is JArray) { AddArray(doc, prefix, token as JArray, fieldconfig?.Items); } else if (token is JValue) { JValue value = token as JValue; bool index = false; bool sort = false; if (fieldconfig != null) { index = fieldconfig.Index; sort = fieldconfig.Sort; } switch (value.Type) //todo: simple date gets detected as string { case JTokenType.Boolean: if (index || sort) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetIntValue((bool)value.Value ? 1 : 0)); } break; case JTokenType.Date: if (index || sort) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetLongValue(((DateTime)value.Value).Ticks)); //doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.SECOND), Field.Store.NO, Field.Index.NOT_ANALYZED)); /* * if (field != null ){ * if (field.IndexType == "datetime") * { * doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.SECOND), Field.Store.NO, Field.Index.NOT_ANALYZED)); * } * else if (field.IndexType == "date") * { * doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.DAY), Field.Store.NO, Field.Index.NOT_ANALYZED)); * } * else if (field.IndexType == "time") * { * doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.SECOND).Substring(8), Field.Store.NO, Field.Index.NOT_ANALYZED)); * } * } * else * { * doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.SECOND), Field.Store.NO, Field.Index.NOT_ANALYZED)); * } */ } break; case JTokenType.Float: if (index || sort) { if (value.Value is float) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetFloatValue((float)value.Value)); } else { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetFloatValue((float)Convert.ToDouble(value.Value))); //doc.Add(new NumericField(prefix, Field.Store.NO, true).SetDoubleValue(Convert.ToDouble(value.Value))); } } break; case JTokenType.Guid: if (index || sort) { doc.Add(new Field(prefix, value.Value.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); } break; case JTokenType.Integer: if (index || sort) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetFloatValue((float)Convert.ToInt64(value.Value))); //doc.Add(new NumericField(prefix, Field.Store.NO, true).SetLongValue(Convert.ToInt64(value.Value))); } break; case JTokenType.Null: break; case JTokenType.String: if (fieldconfig != null && fieldconfig.IndexType == "key") { doc.Add(new Field(prefix, QueryParser.Escape(value.Value.ToString()), Field.Store.NO, Field.Index.NOT_ANALYZED)); } else if (fieldconfig != null && fieldconfig.IndexType == "html") { if (index) { doc.Add(new Field(prefix, HtmlUtils.Clean(value.Value.ToString(), true), Field.Store.NO, Field.Index.ANALYZED)); } if (sort) { doc.Add(new Field("@" + prefix, HtmlUtils.Clean(Truncate(value.Value.ToString(), 100), true), Field.Store.NO, Field.Index.NOT_ANALYZED)); } } else { if (index) { doc.Add(new Field(prefix, value.Value.ToString(), Field.Store.NO, Field.Index.ANALYZED)); } if (sort) { doc.Add(new Field("@" + prefix, Truncate(value.Value.ToString(), 100), Field.Store.NO, Field.Index.NOT_ANALYZED)); } } break; case JTokenType.TimeSpan: if (index || sort) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetLongValue(((TimeSpan)value.Value).Ticks)); } break; case JTokenType.Uri: if (index || sort) { doc.Add(new Field(prefix, value.Value.ToString(), Field.Store.NO, Field.Index.ANALYZED)); } break; default: Debug.Fail("Unsupported JValue type: " + value.Type); break; } } else { Debug.Fail("Unsupported JToken: " + token); } }
public virtual PagedList <Models.ResultObject> Search(string key, int pageIndex, int pageSize, params string[] folders) { var indexDirectory = FSDirectory.Open(new DirectoryInfo(indexDir)); if (!IndexReader.IndexExists(indexDirectory) || string.IsNullOrEmpty(key) && (folders == null || folders.Length == 0)) { return(new PagedList <ResultObject>(new ResultObject[0], pageIndex, pageSize, 0)); } var query = new BooleanQuery(); key = QueryParser.Escape(key.Trim().ToLower()); if (string.IsNullOrEmpty(key)) { key = "*:*"; } QueryParser titleParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, Converter.TitleFieldName, this.Analyzer); var titleQuery = titleParser.Parse(key); titleQuery.Boost = 2; query.Add(new BooleanClause(titleQuery, Occur.SHOULD)); QueryParser bodyParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_30, Converter.BodyFieldName, this.Analyzer); var bodyQuery = bodyParser.Parse(key); bodyQuery.Boost = 1; query.Add(new BooleanClause(bodyQuery, Occur.SHOULD)); QueryWrapperFilter filter = null; if (folders != null && folders.Length > 0) { var folderQuery = new BooleanQuery(); //QueryParser folderParser = new QueryParser(Lucene.Net.Util.Version.LUCENE_29, "FolderName", this.Analyzer); foreach (var folder in folders) { var termQuery = new TermQuery(new Term("FolderName", folder)); termQuery.Boost = 3; folderQuery.Add(new BooleanClause(termQuery, Occur.SHOULD)); } filter = new QueryWrapperFilter(folderQuery); } var searcher = new IndexSearcher(indexDirectory, true); var collecltor = TopScoreDocCollector.Create(searcher.MaxDoc, false); if (filter == null) { searcher.Search(query, collecltor); } else { searcher.Search(query, filter, collecltor); } var lighter = new Highlighter(new SimpleHTMLFormatter("<strong class='highlight'>", "</strong>"), new Lucene.Net.Search.Highlight.QueryScorer((Query)query)); var startIndex = (pageIndex - 1) * pageSize; List <ResultObject> results = new List <ResultObject>(); foreach (var doc in collecltor.TopDocs(startIndex, pageSize).ScoreDocs) { var document = searcher.Doc(doc.Doc); ResultObject result = Converter.ToResultObject(lighter, document); if (result != null) { results.Add(result); } } return(new PagedList <ResultObject>(results, pageIndex, pageSize, collecltor.TotalHits)); }
public async Task <IActionResult> Index(string id, string q, PagerParameters pagerParameters) { var siteSettings = await _siteService.GetSiteSettingsAsync(); Pager pager = new Pager(pagerParameters, siteSettings.PageSize); var indexName = "Search"; if (!String.IsNullOrWhiteSpace(id)) { indexName = id; } if (!_luceneIndexProvider.Exists(indexName)) { return(NotFound()); } if (String.IsNullOrWhiteSpace(q)) { return(View(new SearchIndexViewModel { Pager = pager, IndexName = id, ContentItems = Enumerable.Empty <ContentItem>() })); } var queryParser = new MultiFieldQueryParser(_luceneSettings.GetVersion(), _luceneSettings.GetSearchFields(), _luceneSettings.GetAnalyzer()); var query = queryParser.Parse(QueryParser.Escape(q)); List <int> contentItemIds = new List <int>(); _luceneIndexProvider.Search(indexName, searcher => { // Fetch one more result than PageSize to generate "More" links TopScoreDocCollector collector = TopScoreDocCollector.Create(pager.PageSize + 1, true); searcher.Search(query, collector); TopDocs hits = collector.TopDocs(pager.GetStartIndex(), pager.PageSize + 1); foreach (var hit in hits.ScoreDocs) { var d = searcher.Doc(hit.Doc, IdSet); contentItemIds.Add(Convert.ToInt32(d.GetField("ContentItemId").StringValue)); } }); var contentItems = new List <ContentItem>(); foreach (var contentItemId in contentItemIds.Take(pager.PageSize)) { var contentItem = await _contentManager.GetAsync(contentItemId); if (contentItem != null) { contentItems.Add(contentItem); } } var model = new SearchIndexViewModel { HasMoreResults = contentItemIds.Count > pager.PageSize, Query = q, Pager = pager, IndexName = id, ContentItems = contentItems }; return(View(model)); }
public string EscapeSpecialCharacters(string value) { return(QueryParser.Escape(value ?? string.Empty)); }
public async Task <IActionResult> Index(string id, string q, PagerParameters pagerParameters) { var siteSettings = await _siteService.GetSiteSettingsAsync(); var pager = new Pager(pagerParameters, siteSettings.PageSize); var indexName = "Search"; if (!string.IsNullOrWhiteSpace(id)) { indexName = id; } if (!_luceneIndexProvider.Exists(indexName)) { return(NotFound()); } if (string.IsNullOrWhiteSpace(q)) { return(View(new SearchIndexViewModel { Pager = pager, IndexName = id, ContentItems = Enumerable.Empty <ContentItem>() })); } var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync(); if (luceneSettings == null) { Logger.LogInformation("Couldn't execute search. No Lucene settings was defined."); return(View(new SearchIndexViewModel { HasMoreResults = false, Query = q, Pager = pager, IndexName = id, ContentItems = Enumerable.Empty <ContentItem>() })); } var queryParser = new MultiFieldQueryParser(LuceneSettings.DefaultVersion, luceneSettings.DefaultSearchFields, new StandardAnalyzer(LuceneSettings.DefaultVersion)); var query = queryParser.Parse(QueryParser.Escape(q)); var contentItemIds = new List <string>(); await _luceneIndexProvider.SearchAsync(indexName, searcher => { // Fetch one more result than PageSize to generate "More" links var collector = TopScoreDocCollector.Create(pager.PageSize + 1, true); searcher.Search(query, collector); var hits = collector.GetTopDocs(pager.GetStartIndex(), pager.PageSize + 1); foreach (var hit in hits.ScoreDocs) { var d = searcher.Doc(hit.Doc, IdSet); contentItemIds.Add(d.GetField("ContentItemId").GetStringValue()); } return(Task.CompletedTask); }); var contentItems = new List <ContentItem>(); foreach (var contentItemId in contentItemIds.Take(pager.PageSize)) { var contentItem = await _contentManager.GetAsync(contentItemId); if (contentItem != null) { contentItems.Add(contentItem); } } var model = new SearchIndexViewModel { HasMoreResults = contentItemIds.Count > pager.PageSize, Query = q, Pager = pager, IndexName = id, ContentItems = contentItems }; return(View(model)); }
/// <summary> /// Adds the given JToken to the specified Document. /// </summary> /// <param name="doc"> /// The Document to add to. /// </param> /// <param name="prefix"> /// The prefix to use for field names. /// </param> /// <param name="token"> /// The JToken to add. /// </param> /// <param name="fieldconfig"></param> private static void Add(Document doc, string prefix, JToken token, FieldConfig fieldconfig) { if (token is JObject) { AddProperties(doc, prefix, token as JObject, fieldconfig); } else if (token is JArray) { var itemsConfig = fieldconfig?.Items; if (fieldconfig != null && fieldconfig.Index && itemsConfig == null) { throw new Exception($"Error indexing Array field {prefix}. No 'Items' section defined in index.json. Please fix your index.json."); } AddArray(doc, prefix, token as JArray, itemsConfig); } else if (token is JValue) { JValue value = token as JValue; bool index = false; bool sort = false; if (fieldconfig != null) { index = fieldconfig.Index; sort = fieldconfig.Sort; } switch (value.Type) //todo: simple date gets detected as string { case JTokenType.Boolean: if (index || sort) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetIntValue((bool)value.Value ? 1 : 0)); } break; case JTokenType.Date: if (index || sort) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetLongValue(((DateTime)value.Value).Ticks)); //doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.SECOND), Field.Store.NO, Field.Index.NOT_ANALYZED)); /* * if (field != null ){ * if (field.IndexType == "datetime") * { * doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.SECOND), Field.Store.NO, Field.Index.NOT_ANALYZED)); * } * else if (field.IndexType == "date") * { * doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.DAY), Field.Store.NO, Field.Index.NOT_ANALYZED)); * } * else if (field.IndexType == "time") * { * doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.SECOND).Substring(8), Field.Store.NO, Field.Index.NOT_ANALYZED)); * } * } * else * { * doc.Add(new Field(prefix, DateTools.DateToString((DateTime)value.Value, DateTools.Resolution.SECOND), Field.Store.NO, Field.Index.NOT_ANALYZED)); * } */ } break; case JTokenType.Float: if (index || sort) { if (value.Value is float) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetFloatValue((float)value.Value)); } else { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetFloatValue((float)Convert.ToDouble(value.Value))); //doc.Add(new NumericField(prefix, Field.Store.NO, true).SetDoubleValue(Convert.ToDouble(value.Value))); } } break; case JTokenType.Guid: if (index || sort) { doc.Add(new Field(prefix, value.Value.ToString(), Field.Store.NO, Field.Index.NOT_ANALYZED)); } break; case JTokenType.Integer: if (index || sort) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetFloatValue((float)Convert.ToInt64(value.Value))); //doc.Add(new NumericField(prefix, Field.Store.NO, true).SetLongValue(Convert.ToInt64(value.Value))); } break; case JTokenType.Null: break; case JTokenType.String: if (fieldconfig != null && fieldconfig.IndexType == "key") { doc.Add(new Field(prefix, QueryParser.Escape(value.Value.ToString()), Field.Store.NO, Field.Index.NOT_ANALYZED)); } else if (fieldconfig != null && fieldconfig.IndexType == "html") { if (index) { doc.Add(new Field(prefix, CleanHtml(value.Value.ToString(), true), Field.Store.NO, Field.Index.ANALYZED)); } if (sort) { doc.Add(new Field("@" + prefix, CleanHtml(Truncate(value.Value.ToString(), 100), true), Field.Store.NO, Field.Index.NOT_ANALYZED)); } } else if (fieldconfig != null && fieldconfig.IndexType == "file") { var val = value.Value.ToString(); if (!string.IsNullOrEmpty(val)) { var fileIndexer = FileIndexerManager.GetFileIndexer(val); if (fileIndexer != null) { var content = fileIndexer.GetContent(val); if (index) { doc.Add(new Field(prefix, content, Field.Store.NO, Field.Index.ANALYZED)); } if (sort) { doc.Add(new Field("@" + prefix, Truncate(content, 100), Field.Store.NO, Field.Index.NOT_ANALYZED)); } } } } else { if (index) { doc.Add(new Field(prefix, value.Value.ToString(), Field.Store.NO, Field.Index.ANALYZED)); } if (sort) { doc.Add(new Field("@" + prefix, Truncate(value.Value.ToString(), 100), Field.Store.NO, Field.Index.NOT_ANALYZED)); } } break; case JTokenType.TimeSpan: if (index || sort) { doc.Add(new NumericField(prefix, Field.Store.NO, true).SetLongValue(((TimeSpan)value.Value).Ticks)); } break; case JTokenType.Uri: if (index || sort) { doc.Add(new Field(prefix, value.Value.ToString(), Field.Store.NO, Field.Index.ANALYZED)); } break; default: Debug.Fail("Unsupported JValue type: " + value.Type); break; } } else { Debug.Fail("Unsupported JToken: " + token); } }
public async Task <IActionResult> Search(SearchIndexViewModel viewModel, PagerParameters pagerParameters) { var permissionsProvider = _permissionProviders.FirstOrDefault(x => x.GetType().FullName == "OrchardCore.Lucene.Permissions"); var permissions = await permissionsProvider.GetPermissionsAsync(); var siteSettings = await _siteService.GetSiteSettingsAsync(); var searchSettings = siteSettings.As <LuceneSettings>(); if (permissions.FirstOrDefault(x => x.Name == "QueryLucene" + searchSettings.SearchIndex + "Index") != null) { if (!await _authorizationService.AuthorizeAsync(User, permissions.FirstOrDefault(x => x.Name == "QueryLucene" + searchSettings.SearchIndex + "Index"))) { return(this.ChallengeOrForbid()); } } else { _logger.LogInformation("Couldn't execute search. The search index doesn't exist."); return(BadRequest("Search is not configured.")); } if (searchSettings.SearchIndex != null && !_luceneIndexProvider.Exists(searchSettings.SearchIndex)) { _logger.LogInformation("Couldn't execute search. The search index doesn't exist."); return(BadRequest("Search is not configured.")); } var luceneSettings = await _luceneIndexingService.GetLuceneSettingsAsync(); if (luceneSettings == null || luceneSettings?.DefaultSearchFields == null) { _logger.LogInformation("Couldn't execute search. No Lucene settings was defined."); return(BadRequest("Search is not configured.")); } var luceneIndexSettings = await _luceneIndexSettingsService.GetSettingsAsync(searchSettings.SearchIndex); if (luceneIndexSettings == null) { _logger.LogInformation($"Couldn't execute search. No Lucene index settings was defined for ({searchSettings.SearchIndex}) index."); return(BadRequest($"Search index ({searchSettings.SearchIndex}) is not configured.")); } //if (string.IsNullOrWhiteSpace(viewModel.Terms)) //{ // return View(new SearchIndexViewModel // { // SearchForm = new SearchFormViewModel("Search__Form") { }, // }); //} var pager = new Pager(pagerParameters, siteSettings.PageSize); // We Query Lucene index var analyzer = _luceneAnalyzerManager.CreateAnalyzer(await _luceneIndexSettingsService.GetIndexAnalyzerAsync(luceneIndexSettings.IndexName)); var queryParser = new MultiFieldQueryParser(LuceneSettings.DefaultVersion, luceneSettings.DefaultSearchFields, analyzer); var query = string.IsNullOrWhiteSpace(viewModel.Terms) ? new MatchAllDocsQuery() : queryParser.Parse(QueryParser.Escape(viewModel.Terms)); // Fetch one more result than PageSize to generate "More" links var start = Math.Max(0, (pager.Page - 1) * pager.PageSize); var end = Math.Max(start, start + pager.PageSize); var queryContentItems = (await _searchQueryService.ExecuteQueryAsync(query, searchSettings.SearchIndex, start, end)); // We Query database to retrieve content items. IQuery <ContentItem> queryDb; if (luceneIndexSettings.IndexLatest) { queryDb = _session.Query <ContentItem, ContentItemIndex>() .Where(x => x.ContentItemId.IsIn(queryContentItems.Item1) && x.Latest == true) .Take(pager.PageSize); } else { queryDb = _session.Query <ContentItem, ContentItemIndex>() .Where(x => x.ContentItemId.IsIn(queryContentItems.Item1) && x.Published == true) .Take(pager.PageSize); } // Sort the content items by their rank in the search results returned by Lucene. var containedItems = (await queryDb.ListAsync()).OrderBy(x => queryContentItems.Item1.IndexOf(x.ContentItemId)); var model = new SearchIndexViewModel { Terms = viewModel.Terms, SearchForm = new SearchFormViewModel("Search__Form") { Terms = viewModel.Terms }, SearchResults = new SearchResultsViewModel("Search__Results") { ContentItems = containedItems.Take(pager.PageSize) }, Pager = (await New.Pager(pager)).TotalItemCount(queryContentItems.Item2).UrlParams(new Dictionary <string, string>() { { "Terms", viewModel.Terms } }) }; return(View(model)); }
private static string Escape(string term) { return(QueryParser.Escape(term).to_lower_invariant()); }
public static Query CreateQuery(string sField, string sSearchCriteria, bool bEscapeCharecters = true) { QueryParser oParser = new QueryParser(LuceneVersion, sField, new StandardAnalyzer(LuceneVersion)); return(oParser.Parse(bEscapeCharecters ? QueryParser.Escape(sSearchCriteria) : sSearchCriteria)); }