コード例 #1
0
ファイル: SearchManager.cs プロジェクト: vahidqsmi/Hatra
        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());
        }
コード例 #2
0
        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;
            }
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        /// <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);
        }
コード例 #5
0
        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);
        }
コード例 #6
0
ファイル: FtsIndexService.cs プロジェクト: junkdood/Otokoneko
        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());
        }
コード例 #7
0
        /// <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);
        }
コード例 #8
0
ファイル: FtsIndexService.cs プロジェクト: junkdood/Otokoneko
        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());
        }
コード例 #9
0
        /// <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);
        }
コード例 #10
0
        /// <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);
        }
コード例 #11
0
ファイル: Extensions.cs プロジェクト: wow64bb/YAFNET
 /// <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));
 }
コード例 #12
0
 public static string EscapeKeyword(string value)
 {
     return(QueryParserBase.Escape(value).Replace("\\*", "*").Replace("\\?", "?"));
 }
コード例 #13
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);
        }
コード例 #14
0
    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);
    }