Browse Source

支持必须包含和不包含指令搜索

懒得勤快 5 years ago
parent
commit
8db95f6c6c

+ 25 - 5
Masuit.LuceneEFCore.SearchEngine/LuceneIndexSearcher.cs

@@ -59,6 +59,16 @@ namespace Masuit.LuceneEFCore.SearchEngine
                 return value;
             }
 
+            list.AddRange(Regex.Matches(keyword, @""".+""").Cast<Match>().Select(m =>
+            {
+                keyword = keyword.Replace(m.Value, "");
+                return m.Value;
+            }));//必须包含的
+            list.AddRange(Regex.Matches(keyword, @"\s-.+\s").Cast<Match>().Select(m =>
+            {
+                keyword = keyword.Replace(m.Value, "");
+                return m.Value.Trim();
+            }));//必须不包含的
             list.AddRange(Regex.Matches(keyword, @"[\u4e00-\u9fa5]+").Cast<Match>().Select(m => m.Value));//中文
             list.AddRange(Regex.Matches(keyword, @"\p{P}?[A-Z]*[a-z]*[\p{P}|\p{S}]*").Cast<Match>().Select(m => m.Value));//英文单词
             list.AddRange(Regex.Matches(keyword, "([A-z]+)([0-9.]+)").Cast<Match>().SelectMany(m => m.Groups.Cast<Group>().Select(g => g.Value)));//英文+数字
@@ -81,7 +91,18 @@ namespace Masuit.LuceneEFCore.SearchEngine
             var terms = CutKeywords(keywords);
             foreach (var term in terms)
             {
-                finalQuery.Add(parser.Parse(term.Replace("~", "") + "~"), Occur.SHOULD);
+                if (term.StartsWith("\""))
+                {
+                    finalQuery.Add(parser.Parse(term.Trim('"')), Occur.MUST);
+                }
+                else if (term.StartsWith("-"))
+                {
+                    finalQuery.Add(parser.Parse(term.Trim('"')), Occur.MUST_NOT);
+                }
+                else
+                {
+                    finalQuery.Add(parser.Parse(term.Replace("~", "") + "~"), Occur.SHOULD);
+                }
             }
             return finalQuery;
         }
@@ -115,8 +136,8 @@ namespace Masuit.LuceneEFCore.SearchEngine
             else
             {
                 // 多字段搜索
-                var multiFieldQueryParser = new MultiFieldQueryParser(Lucene.Net.Util.LuceneVersion.LUCENE_48, options.Fields.ToArray(), _analyzer, options.Boosts);
-                query = GetFuzzyquery(multiFieldQueryParser, options.Keywords);
+                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>
@@ -126,13 +147,12 @@ namespace Masuit.LuceneEFCore.SearchEngine
             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"));
+                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();

+ 6 - 6
Masuit.LuceneEFCore.SearchEngine/Masuit.LuceneEFCore.SearchEngine.csproj

@@ -4,23 +4,23 @@
         <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
         <Authors>懒得勤快</Authors>
         <Company>懒得勤快</Company>
-        <Product>基于EntityFrameworkCore和Lucene.NET实现的全文检索搜索引擎,主键int版本</Product>
+        <Product>基于EntityFrameworkCore和Lucene.NET实现的全文检索搜索引擎,主键long版本</Product>
         <Description>基于EntityFrameworkCore和Lucene.NET实现的全文检索搜索引擎</Description>
         <Copyright>懒得勤快</Copyright>
         <PackageProjectUrl>https://github.com/ldqk/Masuit.LuceneEFCore.SearchEngine</PackageProjectUrl>
-        <PackageId>Masuit.LuceneEFCore.SearchEngine_guid</PackageId>
-        <Version>1.1.0</Version>
+        <PackageId>Masuit.LuceneEFCore.SearchEngine_long</PackageId>
+        <Version>1.1.1</Version>
         <Configurations>Debug;Release;String版本;Guid版本;Long版本</Configurations>
         <RunAnalyzersDuringBuild>false</RunAnalyzersDuringBuild>
         <RunAnalyzersDuringLiveAnalysis>false</RunAnalyzersDuringLiveAnalysis>
-        <PackageReleaseNotes>升级.net5</PackageReleaseNotes>
+        <PackageReleaseNotes>支持""和-指令</PackageReleaseNotes>
         <PackageRequireLicenseAcceptance>False</PackageRequireLicenseAcceptance>
         <PublishRepositoryUrl>true</PublishRepositoryUrl>
         <IncludeSymbols>true</IncludeSymbols>
         <SymbolPackageFormat>snupkg</SymbolPackageFormat>
         <LangVersion>9</LangVersion>
-        <FileVersion>1.1</FileVersion>
-        <AssemblyVersion>1.1</AssemblyVersion>
+        <FileVersion>1.1.1</FileVersion>
+        <AssemblyVersion>1.1.1</AssemblyVersion>
     </PropertyGroup>
 
     <ItemGroup>

+ 10 - 41
Masuit.LuceneEFCore.SearchEngine/SearchOptions.cs

@@ -27,26 +27,23 @@ namespace Masuit.LuceneEFCore.SearchEngine
         public int MaximumNumberOfHits { get; set; }
 
         /// <summary>
-        /// 多字段搜索时,给字段的搜索加速
+        /// 多字段搜索时,给字段设定搜索权重
         /// </summary>
-        private Dictionary<string, float> boosts;
+        private Dictionary<string, float> _boosts;
 
         /// <summary>
-        /// 多字段搜索时,给字段的搜索加速
+        /// 多字段搜索时,给字段设定搜索权重
         /// </summary>
-        public Dictionary<string, float> Boosts
+        internal Dictionary<string, float> Boosts
         {
             get
             {
-                foreach (var field in Fields)
+                foreach (var field in Fields.Where(field => _boosts.All(x => x.Key.ToUpper() != field.ToUpper())))
                 {
-                    if (boosts.All(x => x.Key.ToUpper() != field.ToUpper()))
-                    {
-                        boosts.Add(field, 1.0f);
-                    }
+                    _boosts.Add(field, 2.0f);
                 }
 
-                return boosts;
+                return _boosts;
             }
         }
 
@@ -75,40 +72,13 @@ namespace Masuit.LuceneEFCore.SearchEngine
         /// </summary>
         public float Score { get; set; } = 0.5f;
 
-        /// <summary>
-        /// 清除多字段搜索时,给字段的搜索加速
-        /// </summary>
-        public void ClearBoosts()
-        {
-            boosts.Clear();
-        }
-
-        /// <summary>
-        /// 添加多字段搜索时,给字段的搜索加速
-        /// </summary>
-        /// <param name="key"></param>
-        /// <param name="value"></param>
-        public void SetBoost(string key, float value)
-        {
-            boosts[key] = value;
-        }
-
-        /// <summary>
-        /// 设置多字段搜索时,给字段的搜索加速
-        /// </summary>
-        /// <param name="boosts"></param>
-        public void SetBoosts(Dictionary<string, float> boosts)
-        {
-            this.boosts = boosts;
-        }
-
         /// <summary>
         /// 搜索选项
         /// </summary>
         /// <param name="keywords">关键词</param>
         /// <param name="fields">限定检索字段</param>
         /// <param name="maximumNumberOfHits">最大检索量</param>
-        /// <param name="boosts">多字段搜索时,给字段的搜索加速</param>
+        /// <param name="boosts">多字段搜索时,给字段设定搜索权重</param>
         /// <param name="type">文档类型</param>
         /// <param name="orderBy">排序字段</param>
         /// <param name="skip">跳过多少条</param>
@@ -119,14 +89,13 @@ namespace Masuit.LuceneEFCore.SearchEngine
             {
                 throw new ArgumentException("搜索关键词不能为空!");
             }
+
             Keywords = keywords;
             MaximumNumberOfHits = maximumNumberOfHits;
             Skip = skip;
             Take = take;
-            this.boosts = boosts ?? new Dictionary<string, float>();
-
+            this._boosts = boosts ?? new Dictionary<string, float>();
             Type = type;
-
             Fields = new List<string>();
             OrderBy = new List<string>();