From 11c7dd096ba60a8ae60a4b4dacc6467dcdf6630a Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Thu, 6 Dec 2018 18:52:03 +0000 Subject: [PATCH] --- devdocs/specs/core-search.txt | 2 +- server/AyaNova/biz/Search.cs | 105 ++++++++++++++----- server/AyaNova/biz/WidgetBiz.cs | 4 + server/AyaNova/models/SearchKey.cs | 3 +- server/AyaNova/util/AySchema.cs | 4 +- test/raven-integration/Search/SearchOps.cs | 9 +- test/raven-integration/Widget/WidgetLists.cs | 2 +- 7 files changed, 88 insertions(+), 41 deletions(-) diff --git a/devdocs/specs/core-search.txt b/devdocs/specs/core-search.txt index 16f4e98d..c7019630 100644 --- a/devdocs/specs/core-search.txt +++ b/devdocs/specs/core-search.txt @@ -86,7 +86,7 @@ asearchkey - objectid (long id of source object) - objecttype (AyaType as int of source object) - inname (bool indicates the search word was in the name of the object) - + - intags (bool indicates teh search word was found in the tags collection for the object) diff --git a/server/AyaNova/biz/Search.cs b/server/AyaNova/biz/Search.cs index b15e747e..ec350f1b 100644 --- a/server/AyaNova/biz/Search.cs +++ b/server/AyaNova/biz/Search.cs @@ -65,7 +65,7 @@ namespace AyaNova.Biz public string Phrase { get; set; } public bool NameOnly { get; set; } public AyaType TypeOnly { get; set; } - // public List Tags { get; set; } + // public List Tags { get; set; } //Note: maxresults of 0 will get all results public int MaxResults { get; set; } @@ -73,7 +73,7 @@ namespace AyaNova.Biz { NameOnly = false; TypeOnly = AyaType.NoType; - // Tags = new List(); + // Tags = new List(); MaxResults = 500; } @@ -213,7 +213,7 @@ namespace AyaNova.Biz //IF TAGS SPECIFIED //BUGBUG: If no valid tags provided, i.e. a single tag of type or id 0 then can skip - // if (searchParameters.Tags.Count > 0) + // if (searchParameters.Tags.Count > 0) // { // //get a count of the search tags (used by both paths below) // var SearchTagCount = searchParameters.Tags.Count; @@ -375,14 +375,50 @@ namespace AyaNova.Biz #region ProcessKeywords into Database - public static void ProcessNewObjectKeywords(long localeId, long objectID, AyaType objectType, string name, params string[] text) + //Class to hold process input parameters + public class SearchIndexProcessObjectParameters { - ProcessKeywords(localeId, objectID, objectType, true, name, text); + public long LocaleId { get; set; } + public long ObjectId { get; set; } + public AyaType ObjectType { get; set; } + public string Name { get; set; } + public List Words { get; set; } + public List Tags { get; set; } + + + public SearchIndexProcessObjectParameters(long localeId, long objectID, AyaType objectType, string name) + { + Words = new List(); + Tags = new List(); + LocaleId = localeId; + ObjectId = objectID; + ObjectType = objectType; + Name = name; + + } + + public SearchIndexProcessObjectParameters AddWord(string s) + { + Words.Add(s); + return this; + } + public SearchIndexProcessObjectParameters AddWord(uint u) + { + Words.Add(u.ToString()); + return this; + } + } - public static void ProcessUpdatedObjectKeywords(long localeId, long objectID, AyaType objectType, string name, params string[] text) + + public static void ProcessNewObjectKeywords(SearchIndexProcessObjectParameters searchIndexObjectParameters)//(long localeId, long objectID, AyaType objectType, string name, params string[] text) { - ProcessKeywords(localeId, objectID, objectType, false, name, text); + ProcessKeywords(searchIndexObjectParameters, true);//localeId, objectID, objectType, true, name, text); + } + + public static void ProcessUpdatedObjectKeywords(SearchIndexProcessObjectParameters searchIndexObjectParameters)// localeId, long objectID, AyaType objectType, string name, params string[] text) + { + ProcessKeywords(searchIndexObjectParameters, false);//localeId, objectID, objectType, false, name, text); } public static void ProcessDeletedObjectKeywords(long objectID, AyaType objectType) @@ -398,14 +434,14 @@ namespace AyaNova.Biz /// Process the keywords into the dictionary /// NOTE: NAME parameter is in ADDITION to the NAME also being on of the strings passed in text parameter /// - private static void ProcessKeywords(long localeId, long objectID, AyaType objectType, bool newRecord, string name, params string[] text) + private static void ProcessKeywords(SearchIndexProcessObjectParameters p, bool newRecord)//long localeId, long objectID, AyaType objectType, string name, params string[] text) { //AyContext ct = ServiceProviderProvider.DBContext; #if (DEBUG) - if ( objectType == AyaType.JobOperations || objectType == AyaType.Locale) + if (p.ObjectType == AyaType.JobOperations || p.ObjectType == AyaType.Locale) { - throw new System.NotSupportedException($"Search::ProcessKeywords - Invalid type presented {objectType}"); + throw new System.NotSupportedException($"Search::ProcessKeywords - Invalid type presented {p.ObjectType}"); } #endif @@ -413,17 +449,17 @@ namespace AyaNova.Biz //IF NOT NEW, DELETE ALL EXISTING ENTRIES FOR OBJECT TYPE AND ID if (!newRecord) { - ProcessDeletedObjectKeywords(objectID, objectType); + ProcessDeletedObjectKeywords(p.ObjectId, p.ObjectType); } - //BREAK STRING ARRAY INTO KEYWORD LIST - List KeyWordList = Break(localeId, text); - + //BREAK OBJECT TEXT STRINGS INTO KEYWORD LIST + List KeyWordList = Break(p.LocaleId, p.Words); + //BREAK NAME STRING - List NameKeyWordList = Break(localeId, name); + List NameKeyWordList = Break(p.LocaleId, p.Name); - //EARLY EXIT IF NO KEYWORDS OR NAME RECORD TO PROCESS - if (KeyWordList.Count == 0 && string.IsNullOrWhiteSpace(name)) + //EARLY EXIT IF NO KEYWORDS OR NAME RECORD OR TAGS TO PROCESS + if (KeyWordList.Count == 0 && string.IsNullOrWhiteSpace(p.Name) && p.Tags.Count==0) { return; } @@ -521,7 +557,7 @@ namespace AyaNova.Biz var NewSearchKeyList = new List(); foreach (MatchingDictionaryEntry E in MatchingKeywordIdList) { - NewSearchKeyList.Add(new SearchKey() { WordId = E.DictionaryId, InName = E.InName, ObjectId = objectID, ObjectType = objectType }); + NewSearchKeyList.Add(new SearchKey() { WordId = E.DictionaryId, InName = E.InName, InTags=E.InTags, ObjectId = p.ObjectId, ObjectType = p.ObjectType }); } var CtSearchKeyAdd = ServiceProviderProvider.DBContext; CtSearchKeyAdd.SearchKey.AddRange(NewSearchKeyList); @@ -529,18 +565,18 @@ namespace AyaNova.Biz //--------------------------------- - - }//eoc //Class to hold temporary list of matching id public class MatchingDictionaryEntry { public bool InName { get; set; } + public bool InTags { get; set; } public long DictionaryId { get; set; } public MatchingDictionaryEntry() { InName = false; + InTags=false; DictionaryId = -1; } } @@ -609,11 +645,24 @@ namespace AyaNova.Biz /// /// /// - /// An array of 0 to * strings of text + /// A stringlist of 0 to * strings of text /// List of strings - internal static List Break(long localeId, params string[] text) + internal static List Break(long localeId, List textStrings)// params string[] text) { - return BreakCore(localeId, false, text); + return BreakCore(localeId, false, textStrings); + } + + /// + /// + /// + /// + /// + /// + internal static List Break(long localeId, string textString)// params string[] text) + { + List textStrings = new List(1); + textStrings.Add(textString); + return BreakCore(localeId, false, textStrings); } /// @@ -621,11 +670,11 @@ namespace AyaNova.Biz /// cards entered /// /// - /// + /// /// - internal static List BreakSearchPhrase(long localeId, params string[] text) + internal static List BreakSearchPhrase(long localeId, List textStrings) { - return BreakCore(localeId, true, text); + return BreakCore(localeId, true, textStrings); } /// @@ -634,7 +683,7 @@ namespace AyaNova.Biz /// // public static System.Collections.Generic.List StopList = null; - internal static List BreakCore(long localeId, bool KeepWildCards, params string[] text) + internal static List BreakCore(long localeId, bool KeepWildCards, List textStrings) { //Get stopwords and CJKIndex flag value LocaleWordBreakingData LocaleSearchData = GetLocaleSearchData(localeId); @@ -651,7 +700,7 @@ namespace AyaNova.Biz //Loop through each of the passed in strings - foreach (string s in text) + foreach (string s in textStrings) { if (s == null || s == "") continue; //get all the characters in a unicode compliant manner... diff --git a/server/AyaNova/biz/WidgetBiz.cs b/server/AyaNova/biz/WidgetBiz.cs index 88a1bf35..bfe3ab39 100644 --- a/server/AyaNova/biz/WidgetBiz.cs +++ b/server/AyaNova/biz/WidgetBiz.cs @@ -99,6 +99,10 @@ namespace AyaNova.Biz EventLogProcessor.LogEventToDatabase(new Event(UserId, outObj.Id, BizType, AyaEvent.Created), ct); //SEARCH INDEXING + var search = new Search.SearchIndexProcessObjectParameters(); + search.Tags=outObj.Tags; + search.Name=outObj.Name; + search.AddWord(outObj.Notes).AddWord(outObj.Name).AddWord(outObj.Serial); Search.ProcessNewObjectKeywords(UserLocaleId, outObj.Id, BizType, outObj.Name, outObj.Notes, outObj.Name, outObj.Serial.ToString()); return outObj; diff --git a/server/AyaNova/models/SearchKey.cs b/server/AyaNova/models/SearchKey.cs index 8d9aed8e..b117e842 100644 --- a/server/AyaNova/models/SearchKey.cs +++ b/server/AyaNova/models/SearchKey.cs @@ -11,7 +11,7 @@ namespace AyaNova.Models { public long Id { get; set; } public uint ConcurrencyToken { get; set; } - + [Required] public long WordId { get; set; } @@ -20,6 +20,7 @@ namespace AyaNova.Models [Required] public AyaType ObjectType { get; set; } public bool InName { get; set; } + public bool InTags { get; set; } } } diff --git a/server/AyaNova/util/AySchema.cs b/server/AyaNova/util/AySchema.cs index a169cb08..9c60b8dd 100644 --- a/server/AyaNova/util/AySchema.cs +++ b/server/AyaNova/util/AySchema.cs @@ -22,7 +22,7 @@ namespace AyaNova.Util //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::PrepareDatabaseForSeeding WHEN NEW TABLES ADDED!!!! private const int DESIRED_SCHEMA_LEVEL = 8; - internal const long EXPECTED_COLUMN_COUNT = 93; + internal const long EXPECTED_COLUMN_COUNT = 94; internal const long EXPECTED_INDEX_COUNT = 20; //!!!!WARNING: BE SURE TO UPDATE THE DbUtil::PrepareDatabaseForSeeding WHEN NEW TABLES ADDED!!!! @@ -145,7 +145,7 @@ namespace AyaNova.Util //LOOKAT: this index is periodically being violated during testing exec("CREATE UNIQUE INDEX asearchdictionary_word_idx ON asearchdictionary (word);"); - exec("CREATE TABLE asearchkey (id BIGSERIAL PRIMARY KEY, wordid bigint not null REFERENCES asearchdictionary (id), objectid bigint not null, objecttype integer not null, inname bool not null)"); + exec("CREATE TABLE asearchkey (id BIGSERIAL PRIMARY KEY, wordid bigint not null REFERENCES asearchdictionary (id), objectid bigint not null, objecttype integer not null, inname bool not null, intags bool not null)"); //create locale text tables exec("CREATE TABLE alocale (id BIGSERIAL PRIMARY KEY, ownerid bigint not null, name varchar(255) not null, stock bool, cjkindex bool default false)"); diff --git a/test/raven-integration/Search/SearchOps.cs b/test/raven-integration/Search/SearchOps.cs index 6dcabf8a..56b08268 100644 --- a/test/raven-integration/Search/SearchOps.cs +++ b/test/raven-integration/Search/SearchOps.cs @@ -353,16 +353,9 @@ namespace raven_integration { const string TEST_SEARCH_PHRASE = "element* aardvark"; - //CREATE A TAG - dynamic D = new JObject(); - D.name = Util.Uniquify("TAGSEARCH"); - ApiResponse a = await Util.PostAsync("Tag", await Util.GetTokenAsync("manager", "l3tm3in"), D.ToString()); - Util.ValidateDataReturnResponseOk(a); - long TagId = a.ObjectResponse["data"]["id"].Value(); - //CREATE A WIDGET - D = new JObject(); + dynamic D = new JObject(); D.name = Util.Uniquify("TAG search test WIDGET TAG AND PHRASE"); D.dollarAmount = 1.11m; D.active = true; diff --git a/test/raven-integration/Widget/WidgetLists.cs b/test/raven-integration/Widget/WidgetLists.cs index f2d707e8..79f9e901 100644 --- a/test/raven-integration/Widget/WidgetLists.cs +++ b/test/raven-integration/Widget/WidgetLists.cs @@ -75,7 +75,7 @@ namespace raven_integration Util.ValidateDataReturnResponseOk(a); Util.ValidateHTTPStatusCode(a, 200); a.ObjectResponse["data"]["key"].Value().Should().Be("widget"); - ((JArray)a.ObjectResponse["data"]["flds"]).Count.Should().Be(8); + ((JArray)a.ObjectResponse["data"]["flds"]).Count.Should().Be(9); a.ObjectResponse["data"]["flds"][3]["lt"].Value().Should().Be("Price"); a = await Util.GetAsync("Widget/FilterOptions", await Util.GetTokenAsync("es", "es"));