Browse Source

修正分页的bug

懒得勤快 6 years ago
parent
commit
599f2a5b26

+ 45 - 0
Masuit.LuceneEFCore.SearchEngine/Linq/LinqExtension.cs

@@ -0,0 +1,45 @@
+using System;
+using System.Linq.Expressions;
+
+namespace Masuit.LuceneEFCore.SearchEngine.Linq
+{
+    /// <summary>
+    /// linq扩展类
+    /// </summary>
+    public static class LinqExtension
+    {
+        /// <summary>
+        /// 与连接
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="left">左条件</param>
+        /// <param name="right">右条件</param>
+        /// <returns></returns>
+        public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
+        {
+            var dateExpr = Expression.Parameter(typeof(T));
+            var parameterReplacer = new ParameterReplacer(dateExpr);
+            var leftwhere = parameterReplacer.Replace(left.Body);
+            var rightwhere = parameterReplacer.Replace(right.Body);
+            var body = Expression.And(leftwhere, rightwhere);
+            return Expression.Lambda<Func<T, bool>>(body, dateExpr);
+        }
+
+        /// <summary>
+        /// 或连接
+        /// </summary>
+        /// <typeparam name="T"></typeparam>
+        /// <param name="left">左条件</param>
+        /// <param name="right">右条件</param>
+        /// <returns></returns>
+        public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
+        {
+            var dateExpr = Expression.Parameter(typeof(T));
+            var parameterReplacer = new ParameterReplacer(dateExpr);
+            var leftwhere = parameterReplacer.Replace(left.Body);
+            var rightwhere = parameterReplacer.Replace(right.Body);
+            var body = Expression.Or(leftwhere, rightwhere);
+            return Expression.Lambda<Func<T, bool>>(body, dateExpr);
+        }
+    }
+}

+ 43 - 0
Masuit.LuceneEFCore.SearchEngine/Linq/ParameterReplacer.cs

@@ -0,0 +1,43 @@
+using System.Linq.Expressions;
+
+namespace Masuit.LuceneEFCore.SearchEngine.Linq
+{
+    /// <summary>
+    /// linq参数替换器
+    /// </summary>
+    public class ParameterReplacer : ExpressionVisitor
+    {
+        /// <summary>
+        /// linq参数替换器
+        /// </summary>
+        /// <param name="paramExpr"></param>
+        public ParameterReplacer(ParameterExpression paramExpr)
+        {
+            this.ParameterExpression = paramExpr;
+        }
+
+        /// <summary>
+        /// 参数表达式
+        /// </summary>
+        public ParameterExpression ParameterExpression { get; private set; }
+
+        /// <summary>
+        /// 表达式替换
+        /// </summary>
+        /// <param name="expr"></param>
+        /// <returns></returns>
+        public Expression Replace(Expression expr)
+        {
+            return this.Visit(expr);
+        }
+        /// <summary>
+        /// 表达式参数访问
+        /// </summary>
+        /// <param name="p"></param>
+        /// <returns></returns>
+        protected override Expression VisitParameter(ParameterExpression p)
+        {
+            return this.ParameterExpression;
+        }
+    }
+}

+ 19 - 28
Masuit.LuceneEFCore.SearchEngine/LuceneIndexSearcher.cs

@@ -6,12 +6,14 @@ using Lucene.Net.Search;
 using Lucene.Net.Store;
 using Masuit.LuceneEFCore.SearchEngine.Extensions;
 using Masuit.LuceneEFCore.SearchEngine.Interfaces;
+using Masuit.LuceneEFCore.SearchEngine.Linq;
 using Microsoft.Extensions.Caching.Memory;
 using Newtonsoft.Json;
 using System;
 using System.Collections.Generic;
 using System.Diagnostics;
 using System.Linq;
+using System.Linq.Expressions;
 using System.Net;
 using System.Net.Http;
 using System.Text.RegularExpressions;
@@ -150,46 +152,35 @@ namespace Masuit.LuceneEFCore.SearchEngine
                 }
 
                 Sort sort = new Sort(sortFields.ToArray());
-                ScoreDoc[] matches = searcher.Search(query, null, options.MaximumNumberOfHits, sort, true, true).ScoreDocs;
-                results.TotalHits = matches.Length;
+                Expression<Func<ScoreDoc, bool>> where = _ => true;
+                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).ToArray();
+                    matches = matches.Skip(options.Skip.Value);
                 }
                 if (options.Take.HasValue)
                 {
-                    matches = matches.Take(options.Take.Value).ToArray();
+                    matches = matches.Take(options.Take.Value);
                 }
 
+                var docs = matches.ToList();
                 // 创建结果集
-                foreach (var match in matches)
+                foreach (var match in docs)
                 {
-                    var id = match.Doc;
-                    var doc = searcher.Doc(id);
-
-                    // 过滤掉已经设置了类型的对象
-                    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
+                    var doc = searcher.Doc(match.Doc);
+                    results.Results.Add(new LuceneSearchResult()
                     {
-                        results.Results.Add(new LuceneSearchResult()
-                        {
-                            Score = match.Score,
-                            Document = doc
-                        });
-                    }
+                        Score = match.Score,
+                        Document = doc
+                    });
                 }
             }
 

+ 1 - 0
Masuit.LuceneEFCore.SearchEngine/Masuit.LuceneEFCore.SearchEngine.csproj

@@ -10,6 +10,7 @@
     <Copyright>懒得勤快</Copyright>
     <PackageProjectUrl>https://github.com/ldqk/Masuit.LuceneEFCore.SearchEngine</PackageProjectUrl>
     <PackageId>Masuit.LuceneEFCore.SearchEngine_int</PackageId>
+    <Version>1.0.1</Version>
   </PropertyGroup>
   <ItemGroup>
     <PackageReference Include="JieBa.Lucene.Analyzer" Version="1.0.1" />