/// <summary> /// function used in fuzzy search /// </summary> /// <param name="grouping"></param> /// <param name="query"></param> private static SearchGrouping CheckTitlesFuzzy(IGrouping <int, SVR_AnimeSeries> grouping, string query) { if (!(grouping?.SelectMany(a => a.GetAllTitles()).Any() ?? false)) { return(null); } SearchGrouping dist = null; foreach (SVR_AnimeSeries item in grouping) { foreach (string title in item.GetAllTitles()) { if (string.IsNullOrEmpty(title)) { continue; } int k = Math.Max(Math.Min((int)(title.Length / 6D), (int)(query.Length / 6D)), 1); if (query.Length <= 4 || title.Length <= 4) { k = 0; } Misc.SearchInfo <IGrouping <int, SVR_AnimeSeries> > result = Misc.DiceFuzzySearch(title, query, k, grouping); if (result.Index == -1) { continue; } SearchGrouping searchGrouping = new SearchGrouping { Distance = result.Distance, Index = result.Index, ExactMatch = result.ExactMatch, Match = title, Results = grouping.OrderBy(a => a.AirDate).ToList() }; if (result.Distance < (dist?.Distance ?? int.MaxValue)) { dist = searchGrouping; } } } return(dist); }
public static List <SearchResult <T> > SearchCollection <T>(string query, IEnumerable <T> list, Func <T, List <string> > selector) { var parallelList = list.ToList().AsParallel(); List <SearchResult <T> > results = parallelList.Select(a => { List <string> titles = selector(a); SearchResult <T> dist = null; foreach (string title in titles) { if (string.IsNullOrEmpty(title)) { continue; } int k = Math.Max(Math.Min((int)(title.Length / 6D), (int)(query.Length / 6D)), 1); if (query.Length <= 4 || title.Length <= 4) { k = 0; } Misc.SearchInfo <T> result = Misc.DiceFuzzySearch(title, query, k, a); if (result.Index == -1) { continue; } SearchResult <T> searchGrouping = new SearchResult <T> { Distance = result.Distance, Index = result.Index, ExactMatch = result.ExactMatch, Match = title, Result = a }; if (result.Distance < (dist?.Distance ?? int.MaxValue)) { dist = searchGrouping; } } return(dist); }).Where(a => a != null && a.Index != -1).ToList().OrderBy(a => a.Index).ThenBy(a => a.Distance).ToList(); return(results); }
private static List <SearchResult> SearchTagsFuzzy(string query, int limit, SVR_JMMUser user, ParallelQuery <AniDB_Tag> allTags) { List <SearchResult> series = new List <SearchResult>(); IEnumerable <Misc.SearchInfo <CustomTag> > customTags = RepoFactory.CustomTag.GetAll().Select(a => { if (user.GetHideCategories().Contains(a.TagName)) { return(null); } Misc.SearchInfo <CustomTag> tag = Misc.DiceFuzzySearch(a.TagName, query, 0, a); if (tag.Index == -1 || tag.Result == null) { return(null); } return(tag); }).Where(a => a != null).OrderBy(a => a.Distance); series.AddRange(customTags.SelectMany(tag => { return(RepoFactory.CrossRef_CustomTag.GetByCustomTagID(tag.Result.CustomTagID) .Select(xref => { if (xref.CrossRefType != (int)CustomTagCrossRefType.Anime) { return null; } SVR_AnimeSeries anime = RepoFactory.AnimeSeries.GetByAnimeID(xref.CrossRefID); // Because we are searching tags, then getting series from it, we need to make sure it's allowed // for example, p**n could have the drugs tag, even though it's not a "p**n tag" if (anime?.GetAnime()?.GetAllTags().FindInEnumerable(user.GetHideCategories()) ?? true) { return null; } return new SearchResult { Distance = tag.Distance, Index = tag.Index, Match = tag.Result.TagName, Result = anime, ExactMatch = tag.ExactMatch }; }).Where(b => b != null).OrderBy(b => b.Distance).ThenBy(b => b.Result.GetSeriesName()).ToList()); }).Take(limit)); limit -= series.Count; var tags = allTags.Select(tag => { var result = Misc.DiceFuzzySearch(tag.TagName, query, 0, tag); if (result.Index == -1 || result.Result == null) { return(null); } return(result); }).Where(a => a != null).OrderBy(a => a.Distance); series.AddRange(tags.SelectMany(tag => { return(RepoFactory.AniDB_Anime_Tag.GetByTagID(tag.Result.TagID) .Select(xref => { var anime = RepoFactory.AnimeSeries.GetByAnimeID(xref.AnimeID); // Because we are searching tags, then getting series from it, we need to make sure it's allowed // for example, p**n could have the drugs tag, even though it's not a "p**n tag" if (anime?.GetAnime()?.GetAllTags().FindInEnumerable(user.GetHideCategories()) ?? true) { return null; } return new SearchResult { Distance = (600D - xref.Weight) / 600, Index = tag.Index, Match = tag.Result.TagName, Result = anime, ExactMatch = tag.ExactMatch }; }).Where(a => a != null).OrderBy(a => a.Distance).ThenBy(a => a.Result.GetSeriesName()).ToList()); }).Take(limit)); return(series); }