Browse Source

优化广告匹配

懒得勤快 3 years ago
parent
commit
db9bf556ff

+ 2 - 2
src/Masuit.MyBlogs.Core/Controllers/HomeController.cs

@@ -136,8 +136,8 @@ namespace Masuit.MyBlogs.Core.Controllers
             ViewBag.Tag = tag;
             viewModel.Posts = posts;
             viewModel.PageParams = new Pagination(page, size, posts.TotalCount, orderBy);
-            viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location());
-            viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
+            viewModel.SidebarAds = AdsService.GetsByWeightedPrice(2, AdvertiseType.SideBar, Request.Location(), keywords: tag);
+            viewModel.ListAdvertisement = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location(), keywords: tag);
             foreach (var item in posts.Data)
             {
                 item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));

+ 3 - 1
src/Masuit.MyBlogs.Core/Controllers/MiscController.cs

@@ -21,7 +21,9 @@ namespace Masuit.MyBlogs.Core.Controllers
         /// MiscService
         /// </summary>
         public IMiscService MiscService { get; set; }
+
         public IWebHostEnvironment HostEnvironment { get; set; }
+
         public ImagebedClient ImagebedClient { get; set; }
 
         /// <summary>
@@ -196,4 +198,4 @@ namespace Masuit.MyBlogs.Core.Controllers
             return ResultData(misc.Mapper<MiscDto>());
         }
     }
-}
+}

+ 2 - 1
src/Masuit.MyBlogs.Core/Controllers/NoticeController.cs

@@ -21,6 +21,7 @@ namespace Masuit.MyBlogs.Core.Controllers
         /// 公告
         /// </summary>
         public INoticeService NoticeService { get; set; }
+
         public ImagebedClient ImagebedClient { get; set; }
 
         /// <summary>
@@ -212,4 +213,4 @@ namespace Masuit.MyBlogs.Core.Controllers
             return ResultData(dto);
         }
     }
-}
+}

+ 4 - 4
src/Masuit.MyBlogs.Core/Controllers/PostController.cs

@@ -89,8 +89,8 @@ namespace Masuit.MyBlogs.Core.Controllers
                 await PostService.Highlight(post, kw);
             }
 
-            ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.InPage, Request.Location(), post.CategoryId);
             var regex = SearchEngine.LuceneIndexSearcher.CutKeywords(string.IsNullOrWhiteSpace(post.Keyword + post.Label) ? post.Title : post.Keyword + post.Label).Select(Regex.Escape).Join("|");
+            ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.InPage, Request.Location(), post.CategoryId, regex);
             var related = await PostService.GetQuery(PostBaseWhere().And(p => p.Id != id && Regex.IsMatch(p.Title + (p.Keyword ?? "") + (p.Label ?? ""), regex)), p => p.AverageViewCount, false).Take(10).Select(p => new { p.Id, p.Title }).Cacheable().ToDictionaryAsync(p => p.Id, p => p.Title);
             ViewBag.Related = related;
             post.ModifyDate = post.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
@@ -130,7 +130,7 @@ namespace Masuit.MyBlogs.Core.Controllers
                 item.ModifyDate = item.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
             }
 
-            ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.InPage, Request.Location(), post.CategoryId);
+            ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.InPage, Request.Location(), post.CategoryId, post.Keyword + "," + post.Label);
             return View(list);
         }
 
@@ -152,7 +152,7 @@ namespace Masuit.MyBlogs.Core.Controllers
             var prev = await PostHistoryVersionService.GetAsync(p => p.PostId == id && p.ModifyDate < post.ModifyDate, p => p.ModifyDate, false);
             ViewBag.Next = next;
             ViewBag.Prev = prev;
-            ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.InPage, Request.Location(), post.CategoryId);
+            ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.InPage, Request.Location(), post.CategoryId, post.Label);
             return CurrentUser.IsAdmin ? View("HistoryVersion_Admin", post) : View(post);
         }
 
@@ -178,7 +178,7 @@ namespace Masuit.MyBlogs.Core.Controllers
             right.ModifyDate = right.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
             left.Content = ReplaceVariables(Regex.Replace(Regex.Replace(diffOutput, "<del.+?</del>", string.Empty), @"<\w+></\w+>", string.Empty));
             left.ModifyDate = left.ModifyDate.ToTimeZone(HttpContext.Session.Get<string>(SessionKey.TimeZone));
-            ViewBag.Ads = AdsService.GetsByWeightedPrice(2, AdvertiseType.InPage, Request.Location(), main.CategoryId);
+            ViewBag.Ads = AdsService.GetsByWeightedPrice(2, AdvertiseType.InPage, Request.Location(), main.CategoryId, main.Label);
             ViewBag.DisableCopy = post.DisableCopy;
             return View(new[] { main, left, right });
         }

+ 2 - 2
src/Masuit.MyBlogs.Core/Controllers/SearchController.cs

@@ -29,7 +29,7 @@ namespace Masuit.MyBlogs.Core.Controllers
         /// <param name="page"></param>
         /// <param name="size"></param>
         /// <returns></returns>
-        [HttpGet("search/{**wd}"), HttpGet("search", Order = 2), HttpGet("s/{**wd}", Order = 3), HttpGet("s", Order = 4)]
+        [HttpGet("search/{**wd:maxlength(64)}"), HttpGet("search", Order = 2), HttpGet("s/{**wd:maxlength(64)}", Order = 3), HttpGet("s", Order = 4)]
         public async Task<ActionResult> Search([FromServices] IPostService postService, string wd = "", [Range(1, int.MaxValue, ErrorMessage = "页码必须大于0")] int page = 1, [Range(1, 50, ErrorMessage = "页大小必须在0到50之间")] int size = 15)
         {
             wd = ChineseConverter.Convert(wd?.Trim() ?? "", ChineseConversionDirection.TraditionalToSimplified);
@@ -46,7 +46,7 @@ namespace Masuit.MyBlogs.Core.Controllers
                 CheckPermission(posts.Results);
                 if (posts.Results.Count > 1)
                 {
-                    ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
+                    ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location(), keywords: wd);
                 }
 
                 ViewBag.hotSearches = new List<KeywordsRank>();

+ 1 - 1
src/Masuit.MyBlogs.Core/Controllers/SeminarController.cs

@@ -54,7 +54,7 @@ namespace Masuit.MyBlogs.Core.Controllers
             ViewBag.Title = s.Title;
             ViewBag.Desc = s.Description;
             ViewBag.SubTitle = s.SubTitle;
-            ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location());
+            ViewBag.Ads = AdsService.GetByWeightedPrice(AdvertiseType.ListItem, Request.Location(), keywords: s.Title);
             ViewData["page"] = new Pagination(page, size, posts.TotalCount, orderBy);
             foreach (var item in posts.Data)
             {

+ 8 - 7
src/Masuit.MyBlogs.Core/Controllers/SubscribeController.cs

@@ -24,6 +24,7 @@ namespace Masuit.MyBlogs.Core.Controllers
     public class SubscribeController : Controller
     {
         public IPostService PostService { get; set; }
+
         public IAdvertisementService AdvertisementService { get; set; }
 
         /// <summary>
@@ -77,11 +78,11 @@ namespace Masuit.MyBlogs.Core.Controllers
             return Content(rss, ContentType.Xml);
         }
 
-        private void InsertAdvertisement(List<Item> posts, int? cid = null)
+        private void InsertAdvertisement(List<Item> posts, int? cid = null, string keywords = "")
         {
             if (posts.Count > 2)
             {
-                var ad = AdvertisementService.GetByWeightedPrice((AdvertiseType)(DateTime.Now.Second % 4 + 1), Request.Location(), cid);
+                var ad = AdvertisementService.GetByWeightedPrice((AdvertiseType)(DateTime.Now.Second % 4 + 1), Request.Location(), cid, keywords);
                 if (ad is not null)
                 {
                     posts.Insert(new Random().Next(1, posts.Count), new Item()
@@ -137,7 +138,7 @@ namespace Masuit.MyBlogs.Core.Controllers
                 };
             });
             var posts = data.ToList();
-            InsertAdvertisement(posts, id);
+            InsertAdvertisement(posts, id, category.Name);
             var feed = new Feed()
             {
                 Title = Request.Host + $":分类{category.Name}文章订阅",
@@ -189,7 +190,7 @@ namespace Masuit.MyBlogs.Core.Controllers
                 };
             });
             var posts = data.ToList();
-            InsertAdvertisement(posts, id);
+            InsertAdvertisement(posts, id, seminar.Title);
             var feed = new Feed()
             {
                 Title = Request.Host + $":专题{seminar.Title}文章订阅",
@@ -259,7 +260,6 @@ namespace Masuit.MyBlogs.Core.Controllers
                    p.LimitMode == RegionLimitMode.AllowRegion ? Regex.IsMatch(location, p.Regions) :
                    p.LimitMode == RegionLimitMode.ForbidRegion ? !Regex.IsMatch(location, p.Regions) :
                    p.LimitMode == RegionLimitMode.AllowRegionExceptForbidRegion ? Regex.IsMatch(location, p.Regions) && !Regex.IsMatch(location, p.ExceptRegions) : !Regex.IsMatch(location, p.Regions) || Regex.IsMatch(location, p.ExceptRegions);
-
         }
 
         private void CheckPermission(Post post)
@@ -274,6 +274,7 @@ namespace Masuit.MyBlogs.Core.Controllers
                     }
 
                     break;
+
                 case RegionLimitMode.ForbidRegion:
                     if (Regex.IsMatch(location, post.Regions) && !Request.IsRobot())
                     {
@@ -281,6 +282,7 @@ namespace Masuit.MyBlogs.Core.Controllers
                     }
 
                     break;
+
                 case RegionLimitMode.AllowRegionExceptForbidRegion:
                     if (Regex.IsMatch(location, post.ExceptRegions))
                     {
@@ -315,6 +317,5 @@ namespace Masuit.MyBlogs.Core.Controllers
             });
             throw new NotFoundException("文章未找到");
         }
-
     }
-}
+}

+ 22 - 6
src/Masuit.MyBlogs.Core/Infrastructure/Services/AdvertisementService.cs

@@ -18,21 +18,24 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
 
         public ICategoryRepository CategoryRepository { get; set; }
 
-        public IAdvertisementClickRecordRepository AdvertisementClickRecordRepository { get; set; }
+        private readonly ILuceneIndexSearcher _luceneIndexSearcher;
 
         public AdvertisementService(IBaseRepository<Advertisement> repository, ISearchEngine<DataContext> searchEngine, ILuceneIndexSearcher searcher) : base(repository, searchEngine, searcher)
         {
+            _luceneIndexSearcher = searcher;
         }
 
         /// <summary>
         /// 按价格随机筛选一个元素
         /// </summary>
         /// <param name="type">广告类型</param>
+        /// <param name="location"></param>
         /// <param name="cid">分类id</param>
+        /// <param name="keywords"></param>
         /// <returns></returns>
-        public Advertisement GetByWeightedPrice(AdvertiseType type, IPLocation location, int? cid = null)
+        public Advertisement GetByWeightedPrice(AdvertiseType type, IPLocation location, int? cid = null, string keywords = "")
         {
-            return GetsByWeightedPrice(1, type, location, cid).FirstOrDefault();
+            return GetsByWeightedPrice(1, type, location, cid, keywords).FirstOrDefault();
         }
 
         /// <summary>
@@ -40,12 +43,14 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
         /// </summary>
         /// <param name="count">数量</param>
         /// <param name="type">广告类型</param>
+        /// <param name="ipinfo"></param>
         /// <param name="cid">分类id</param>
+        /// <param name="keywords"></param>
         /// <returns></returns>
-        public List<Advertisement> GetsByWeightedPrice(int count, AdvertiseType type, IPLocation ipinfo, int? cid = null)
+        public List<Advertisement> GetsByWeightedPrice(int count, AdvertiseType type, IPLocation ipinfo, int? cid = null, string keywords = "")
         {
             var (location, _, _) = ipinfo;
-            return CacheManager.GetOrAdd($"Advertisement:{location.Crc32()}:{type}:{count}-{cid}", _ =>
+            return CacheManager.GetOrAdd($"Advertisement:{location.Crc32()}:{type}:{count}-{cid}-{keywords}", _ =>
             {
                 var atype = type.ToString("D");
                 Expression<Func<Advertisement, bool>> where = a => a.Types.Contains(atype) && a.Status == Status.Available;
@@ -60,9 +65,20 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services
                     }
                 }
 
+                if (!keywords.IsNullOrEmpty())
+                {
+                    var regex = _luceneIndexSearcher.CutKeywords(keywords).Select(Regex.Escape).Join("|");
+                    where = where.And(a => Regex.IsMatch(a.Title + a.Description, regex));
+                }
+
                 var list = GetQuery(where).OrderBy(a => -Math.Log(DataContext.Random()) / ((double)a.Price / a.Types.Length * catCount / (string.IsNullOrEmpty(a.CategoryIds) ? catCount : (a.CategoryIds.Length + 1)))).Take(count).ToList();
+                if (list.Count == 0 && keywords is { Length: > 0 })
+                {
+                    return GetsByWeightedPrice(count, type, ipinfo, cid);
+                }
+
                 var ids = list.Select(a => a.Id).ToArray();
-                GetQuery(a => ids.Contains(a.Id)).UpdateFromQuery(a => new Advertisement()
+                GetQuery(a => ids.Contains(a.Id)).UpdateFromQuery(a => new Advertisement
                 {
                     DisplayCount = a.DisplayCount + 1
                 });

+ 7 - 3
src/Masuit.MyBlogs.Core/Infrastructure/Services/Interface/IAdvertisementService.cs

@@ -10,17 +10,21 @@ namespace Masuit.MyBlogs.Core.Infrastructure.Services.Interface
         /// 按价格随机筛选一个元素
         /// </summary>
         /// <param name="type">广告类型</param>
+        /// <param name="location"></param>
         /// <param name="cid">分类id</param>
+        /// <param name="keywords"></param>
         /// <returns></returns>
-        Advertisement GetByWeightedPrice(AdvertiseType type, IPLocation location, int? cid = null);
+        Advertisement GetByWeightedPrice(AdvertiseType type, IPLocation location, int? cid = null, string keywords = null);
 
         /// <summary>
         /// 按价格随机筛选多个元素
         /// </summary>
         /// <param name="count">数量</param>
         /// <param name="type">广告类型</param>
+        /// <param name="location"></param>
         /// <param name="cid">分类id</param>
+        /// <param name="keywords"></param>
         /// <returns></returns>
-        List<Advertisement> GetsByWeightedPrice(int count, AdvertiseType type, IPLocation location, int? cid = null);
+        List<Advertisement> GetsByWeightedPrice(int count, AdvertiseType type, IPLocation location, int? cid = null, string keywords = null);
     }
-}
+}