public SearchResultCollection Search(string searchQuery, int hitsStart, int hitsStop, string[] fields) { if (string.IsNullOrEmpty(searchQuery)) { return(new SearchResultCollection()); } const int hitsLimit = 100; SearchResultCollection results; using (var analyzer = new StandardAnalyzer(LuceneVersion)) { using (var reader = DirectoryReader.Open(Directory)) { var searcher = new IndexSearcher(reader); var parser = new MultiFieldQueryParser(LuceneVersion, fields, analyzer); var query = parser.Parse(QueryParserBase.Escape(searchQuery.Trim())); var hits = searcher.Search(query, null, hitsLimit, Sort.RELEVANCE).ScoreDocs; results = new SearchResultCollection { Count = hits.Length, Data = hits.Where((x, i) => i >= hitsStart && i < hitsStop) .Select(x => new SearchResult(searcher.Doc(x.Doc))) .ToList() }; //var res=new LuceneSearchModel() } } //return results; return(new SearchResultCollection()); }
private IList <Document> Search(string searchText, string itemsFolder, string[] fieldNames) { if (string.IsNullOrEmpty(searchText)) { return(new List <Document>()); } try { using var analyzer = new EnglishAnalyzer(LuceneVersion.LUCENE_48); using var reader = DirectoryReader.Open(GetDirectory(itemsFolder)); var searcher = new IndexSearcher(reader); var parser = new MultiFieldQueryParser(LuceneVersion.LUCENE_48, fieldNames, analyzer); var query = parser.Parse(QueryParserBase.Escape(searchText.Trim())); //TODO: change 100 to page size when paging is implemented var hits = searcher.Search(query, null, 100, Sort.RELEVANCE).ScoreDocs; return(hits.Select(x => searcher.Doc(x.Doc)).ToList()); } catch (Exception ex) { throw; } }
private static TopDocs Search(string text, IndexSearcher searcher) { var qp = new QueryParser(LuceneVersion.LUCENE_48, "text", new StandardAnalyzer(LuceneVersion.LUCENE_48)); var escapedString = QueryParserBase.Escape(text); var idQuery = qp.Parse(escapedString); var hits = searcher.Search(idQuery, 999999999); return(hits); }
/// <inheritdoc /> public ISearchBuilder WithinRange(string field, string minimun, string maximun, bool includeMinimun = true, bool includeMaximun = true) { CreatePendingClause(); var minimunBytesRef = minimun != null ? new BytesRef(QueryParserBase.Escape(minimun)) : null; var maximunBytesRef = maximun != null ? new BytesRef(QueryParserBase.Escape(maximun)) : null; _query = new TermRangeQuery(field, minimunBytesRef, maximunBytesRef, includeMinimun, includeMaximun); return(this); }
public static Query ParseQuery(string searchQuery, QueryParser parser) { Query query; try { query = parser.Parse(searchQuery.Trim()); } catch (ParseException) { query = parser.Parse(QueryParserBase.Escape(searchQuery.Trim())); } return(query); }
public List <long> TagFts(string queryString) { queryString = QueryParserBase.Escape(queryString); using var ftsDirectory = FSDirectory.Open(TagIndexPath); using var ftsIndexReader = DirectoryReader.Open(ftsDirectory); var ftsIndexSearch = new IndexSearcher(ftsIndexReader); var nameParser = new QueryParser(AppLuceneVersion, "Name", Analyzer); var detailParser = new QueryParser(AppLuceneVersion, "Detail", Analyzer); var query = new BooleanQuery { { nameParser.Parse(queryString + "*"), Occur.SHOULD }, { detailParser.Parse(queryString), Occur.SHOULD }, }; var hits = ftsIndexSearch.Search(query, int.MaxValue).ScoreDocs.ToList(); return(hits.Select(hit => long.Parse(ftsIndexSearch.Doc(hit.Doc).Get("Id"))).Distinct().ToList()); }
/// <seealso cref="IQualityQueryParser.Parse(QualityQuery)"/> public virtual Query Parse(QualityQuery qq) { QueryParser qp = queryParser.Value; if (qp is null) { #pragma warning disable 612, 618 qp = new QueryParser(LuceneVersion.LUCENE_CURRENT, indexField, new StandardAnalyzer(LuceneVersion.LUCENE_CURRENT)); #pragma warning restore 612, 618 queryParser.Value = qp; } BooleanQuery bq = new BooleanQuery(); for (int i = 0; i < qqNames.Length; i++) { bq.Add(qp.Parse(QueryParserBase.Escape(qq.GetValue(qqNames[i]))), Occur.SHOULD); } return(bq); }
public List <long> MangaFts(string queryString) { queryString = QueryParserBase.Escape(queryString); using var ftsDirectory = FSDirectory.Open(MangaIndexPath); using var ftsIndexReader = DirectoryReader.Open(ftsDirectory); var ftsIndexSearch = new IndexSearcher(ftsIndexReader); var titleParser = new QueryParser(AppLuceneVersion, "Title", Analyzer); var descriptionParser = new QueryParser(AppLuceneVersion, "Description", Analyzer); var aliasesParser = new QueryParser(AppLuceneVersion, "Aliases", Analyzer); var query = new BooleanQuery { { new BoostedQuery(titleParser.Parse(queryString), new DoubleConstValueSource(2.0)), Occur.SHOULD }, { new BoostedQuery(descriptionParser.Parse(queryString), new DoubleConstValueSource(0.5)), Occur.SHOULD }, { new BoostedQuery(aliasesParser.Parse(queryString), new DoubleConstValueSource(1.0)), Occur.SHOULD } }; var hits = ftsIndexSearch.Search(query, int.MaxValue).ScoreDocs.ToList(); return(hits.Select(hit => long.Parse(ftsIndexSearch.Doc(hit.Doc).Get("Id"))).ToList()); }
/// <inheritdoc /> public ISearchBuilder Parse(string query, bool escape = true, params string[] defaultFields) { Prevent.ParameterNullOrWhiteSpace(query, nameof(query)); Prevent.ParameterNull(defaultFields, nameof(defaultFields)); if (defaultFields.Length == 0) { throw new ArgumentException("Default fields can't be empty."); } if (escape) { query = QueryParserBase.Escape(query); } foreach (var defaultField in defaultFields) { CreatePendingClause(); _query = new QueryParser(IndexProvider.Version, defaultField, _analyzer).Parse(query); } return(this); }
/// <summary> /// 执行搜索 /// </summary> /// <param name="options">搜索选项</param> /// <param name="safeSearch">启用安全搜索</param> /// <returns></returns> private ILuceneSearchResultCollection PerformSearch(SearchOptions options, bool safeSearch) { // 结果集 ILuceneSearchResultCollection results = new LuceneSearchResultCollection(); using var reader = DirectoryReader.Open(_directory); var searcher = new IndexSearcher(reader); Query query; // 启用安全搜索 if (safeSearch) { options.Keywords = QueryParserBase.Escape(options.Keywords); } if (options.Fields.Count == 1) { // 单字段搜索 var queryParser = new QueryParser(Lucene.Net.Util.LuceneVersion.LUCENE_48, options.Fields[0], _analyzer); query = queryParser.Parse(options.Keywords); } else { // 多字段搜索 var queryParser = new MultiFieldQueryParser(Lucene.Net.Util.LuceneVersion.LUCENE_48, options.Fields.ToArray(), _analyzer, options.Boosts); query = GetFuzzyquery(queryParser, options.Keywords); } var sortFields = new List <SortField> { SortField.FIELD_SCORE }; sortFields.AddRange(options.OrderBy.Select(sortField => new SortField(sortField, SortFieldType.STRING))); // 排序规则处理 var sort = new Sort(sortFields.ToArray()); Expression <Func <ScoreDoc, bool> > where = m => m.Score >= options.Score; if (options.Type != null) { // 过滤掉已经设置了类型的对象 where = where.And(m => options.Type.AssemblyQualifiedName == searcher.Doc(m.Doc).Get("Type")); } var matches = searcher.Search(query, null, options.MaximumNumberOfHits, sort, true, true).ScoreDocs.Where(@where.Compile()); results.TotalHits = matches.Count(); // 分页处理 if (options.Skip.HasValue) { matches = matches.Skip(options.Skip.Value); } if (options.Take.HasValue) { matches = matches.Take(options.Take.Value); } var docs = matches.ToList(); // 创建结果集 foreach (var match in docs) { var doc = searcher.Doc(match.Doc); results.Results.Add(new LuceneSearchResult() { Score = match.Score, Document = doc }); } return(results); }
/// <summary> /// Escapes an extension field. The default implementation is equivalent to /// <see cref="QueryParserBase.Escape(string)"/>. /// </summary> /// <param name="extfield">the extension field identifier</param> /// <returns>the extension field identifier with all special chars escaped with /// a backslash character.</returns> public virtual string EscapeExtensionField(string extfield) { return(QueryParserBase.Escape(extfield)); }
public static string EscapeKeyword(string value) { return(QueryParserBase.Escape(value).Replace("\\*", "*").Replace("\\?", "?")); }
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); }
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, "[\\*\\-_]", string.Empty); //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 = QueryParserBase.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 = QueryParserBase.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); }