From ff36baaf579c5c209ec82155032b1d69fbd2f28a Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Tue, 7 Apr 2020 23:21:19 +0000 Subject: [PATCH] --- server/AyaNova/biz/Search.cs | 85 +++++++++++++++++++++++------------- 1 file changed, 54 insertions(+), 31 deletions(-) diff --git a/server/AyaNova/biz/Search.cs b/server/AyaNova/biz/Search.cs index 4c65083b..6aa1607d 100644 --- a/server/AyaNova/biz/Search.cs +++ b/server/AyaNova/biz/Search.cs @@ -121,7 +121,17 @@ namespace AyaNova.Biz return ReturnObject; } - //IF PHRASE SPECIFIED + // todo: SEARCH UI + // - all searches without wildcards or quotes are "contains" searches by default and multiple phrases space delimited are accomodated + // - if user want's an exact search then they put it in quotes like google for MUST have in that exact form and case (if case insensitive mode) + + + //IF PHRASE SPECIFIED <---wtf? why wouldn't it be? + + //escape literal percentage signs first just in case they are searching for 50% off or something + //https://www.postgresql.org/docs/current/functions-matching.html#FUNCTIONS-LIKE + //need to get around breaking possibly losing the symbol so make it text + searchParameters.Phrase = searchParameters.Phrase.Replace("%", "pctsym"); //Modify Phrase to replace wildcard * with % as breakcore expects sql style wildcards searchParameters.Phrase = searchParameters.Phrase.Replace("*", "%"); @@ -130,15 +140,15 @@ namespace AyaNova.Biz var PhraseItems = await BreakSearchPhraseAsync(translationId, searchParameters.Phrase); //SPLIT OUT WILDCARDS FROM NON WILDCARDS - List WildCardSearchTerms = new List(); - List RegularSearchTerms = new List(); + List PreWildCardedSearchTerms = new List(); + List SearchTerms = new List(); foreach (string PhraseItem in PhraseItems) { if (PhraseItem.Contains("%")) - WildCardSearchTerms.Add(PhraseItem); + PreWildCardedSearchTerms.Add(PhraseItem.Replace("pctsym", @"\%"));//put back literal percentage symbol if necessary else - RegularSearchTerms.Add(PhraseItem); + SearchTerms.Add(PhraseItem.Replace("pctsym", @"\%"));//put back literal percentage symbol if necessary } @@ -148,15 +158,19 @@ namespace AyaNova.Biz //GET LIST OF DICTIONARY ID'S THAT MATCH REGULAR SEARCH TERMS - if (RegularSearchTerms.Count > 0) - DictionaryMatches = await ct.SearchDictionary.Where(m => RegularSearchTerms.Contains(m.Word)).Select(m => m.Id).ToListAsync(); + if (SearchTerms.Count > 0) + //DictionaryMatches = await ct.SearchDictionary.Where(m => SearchTerms.Contains(m.Word)).Select(m => m.Id).ToListAsync(); + foreach (string Term in SearchTerms) + { + DictionaryMatches.AddRange(await ct.SearchDictionary.Where(m => m.Word.Contains(Term)).Select(m => m.Id).ToListAsync()); + } //GET LIST OF DICTIONARY ID'S THAT MATCH WILDCARD SEARCH TERMS - if (WildCardSearchTerms.Count > 0) + if (PreWildCardedSearchTerms.Count > 0) { - foreach (string WildCardSearchTerm in WildCardSearchTerms) + foreach (string WildCardSearchTerm in PreWildCardedSearchTerms) { //Contains? if (WildCardSearchTerm.StartsWith("%") && WildCardSearchTerm.EndsWith("%")) @@ -175,7 +189,7 @@ namespace AyaNova.Biz } //SEARCH SEARCHKEY FOR MATCHING WORDS AND OPTIONALLY TYPE AND INNAME - var TotalSearchTermsToMatch = WildCardSearchTerms.Count + RegularSearchTerms.Count; + var TotalSearchTermsToMatch = PreWildCardedSearchTerms.Count + SearchTerms.Count; // var TestRawMatches = await ct.SearchKey.Where(x => DictionaryMatches.Contains(x.WordId)).ToListAsync(); @@ -706,24 +720,24 @@ cache or provide directly the translation to save time repeatedly fetching it wh } } -private static Dictionary translationWordBreakingDataCache = new Dictionary(); + private static Dictionary translationWordBreakingDataCache = new Dictionary(); -// //called at startup to populate cache -//WAS GOING TO ADD THIS IN RESPONSE TO AN ISSUE WITH EXCEPTION ATTEMPTING TO ADD ALREADY EXISTING DICTIONARY ID 1, BUT IT NEVER HAPPENED AGAIN, SO :SHRUGEMOJI: -//IF IT DOES, MAKE THIS CODE AND POPULATE IT AT SERVER BOOT AND SHOULD BE ADEQUATE -//OR GO NUTS WITH A FULL MEMORY CACHE: https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-3.1 -// internal static async Task CacheAllTranslationWordBreakingData(){ -// //iterate all Translations, cache the word break data -// l = await ct.Translation -// .AsNoTracking() -// .OrderBy(m => m.Name) -// .Select(m => new NameIdItem() -// { -// Id = m.Id, -// Name = m.Name -// }).ToListAsync(); -// TranslationWordBreakingDataCache.Add(TranslationId, await GetTranslationSearchDataAsync(TranslationId)); -// } + // //called at startup to populate cache + //WAS GOING TO ADD THIS IN RESPONSE TO AN ISSUE WITH EXCEPTION ATTEMPTING TO ADD ALREADY EXISTING DICTIONARY ID 1, BUT IT NEVER HAPPENED AGAIN, SO :SHRUGEMOJI: + //IF IT DOES, MAKE THIS CODE AND POPULATE IT AT SERVER BOOT AND SHOULD BE ADEQUATE + //OR GO NUTS WITH A FULL MEMORY CACHE: https://docs.microsoft.com/en-us/aspnet/core/performance/caching/memory?view=aspnetcore-3.1 + // internal static async Task CacheAllTranslationWordBreakingData(){ + // //iterate all Translations, cache the word break data + // l = await ct.Translation + // .AsNoTracking() + // .OrderBy(m => m.Name) + // .Select(m => new NameIdItem() + // { + // Id = m.Id, + // Name = m.Name + // }).ToListAsync(); + // TranslationWordBreakingDataCache.Add(TranslationId, await GetTranslationSearchDataAsync(TranslationId)); + // } internal static async Task GetTranslationSearchDataAsync(long translationId, AyContext ct = null) { TranslationWordBreakingData LSD = new TranslationWordBreakingData(); @@ -792,7 +806,8 @@ private static Dictionary translationWordBrea { List textStrings = new List(); textStrings.Add(searchPhrase); - return await BreakCoreAsync(translationId, true, textStrings); + //note: we want stopwords if this is a search phrase break because they might type "some" wanting awesome but some is a stopword so.. + return await BreakCoreAsync(translationId, true, textStrings, true); } /// @@ -801,7 +816,7 @@ private static Dictionary translationWordBrea /// - internal static async Task> BreakCoreAsync(long translationId, bool KeepWildCards, List textStrings) + internal static async Task> BreakCoreAsync(long translationId, bool KeepWildCards, List textStrings, bool ignoreStopWords = false) { //For stopwords and CJKIndex flag value //if not provided (will be provided by seeder for performance but normally never) then fetch @@ -1075,11 +1090,19 @@ private static Dictionary translationWordBrea //but keep them if they are part of a wildcard search phrase if (s.Length >= MINWORDLENGTH || (KeepWildCards && s.Contains('%'))) { - //Add only non stopwords - if (!translationWordBreakData.StopWords.Contains(s)) + if (ignoreStopWords) { + //breaking of search phrase ReturnList.Add(s); } + else + { + //Add only non stopwords - regular breaking of object for dictionary entry + if (!translationWordBreakData.StopWords.Contains(s)) + { + ReturnList.Add(s); + } + } } }