//public readonly double LogicalScore; public ProductLink(Engine engine, Product[] product1s, Product[] product2s) { this.Engine = engine; Product1s = product1s; Product2s = product2s; MutualCompanyIds = (from p1 in product1s join p2 in product2s on p1.DbProduct.CompanyId equals p2.DbProduct.CompanyId where p1 != null && p2 != null select p1.DbProduct.CompanyId).ToList(); if (MutualCompanyIds.Count > 0) { MutualProductIds = (from p1 in product1s join p2 in product2s on p1.DbProduct.Id equals p2.DbProduct.Id where p1 != null && p2 != null select p1.DbProduct.Id).ToList(); if (MutualProductIds.Count < MutualCompanyIds.Count)//chains contain different products of the same company so cannot be linked Score = -1.1; else //chains contain the same products so should be considered linked Score = 1.1; return; } foreach (Product product1 in Product1s) foreach (Product product2 in Product2s) Set(product1.DbProduct.Id, product2.DbProduct.Id, new ProductPair(engine, product1, product2)); //word order //word density CategoryScore = (double)product1_id_product2_id_s2ProductPair.Values.Select(x => x.CategoryScore).Sum() / product1_id_product2_id_s2ProductPair.Count; NameScore = (double)product1_id_product2_id_s2ProductPair.Values.Select(x => x.NameScore).Sum() / product1_id_product2_id_s2ProductPair.Count; Score = 0.6 * CategoryScore + 0.4 * NameScore; }
internal Product Get(int product_id) { Product p = null; if (!product_ids2Product.TryGetValue(product_id, out p)) { Fhr.ProductOffice.Models.Product product = engine.Db.Products.Where(x => x.Id == product_id).FirstOrDefault(); if (product == null) throw new Exception("No Product with Id=" + product_id); p = new Product(engine, product); product_ids2Product[product.Id] = p; } return p; }
internal void MapCategories(Product product1, Product product2) { Dictionary<string, HashSet<string>> category1s_to_mapped_category2s; string company1_id_company2_id = get_company_pair_key(ref product1, ref product2); if (!company1_id_company2_id_to_category1s_to_mapped_category2s.TryGetValue(company1_id_company2_id, out category1s_to_mapped_category2s)) { category1s_to_mapped_category2s = new Dictionary<string, HashSet<string>>(); company1_id_company2_id_to_category1s_to_mapped_category2s[company1_id_company2_id] = category1s_to_mapped_category2s; } HashSet<string> mapped_category2s; if (!category1s_to_mapped_category2s.TryGetValue(product1.DbProduct.Category, out mapped_category2s)) { mapped_category2s = new HashSet<string>(); category1s_to_mapped_category2s[product1.DbProduct.Category] = mapped_category2s; } mapped_category2s.Add(product2.DbProduct.Category); }
internal double GetCategoryComparisonScore(Product product1, Product product2) { Dictionary<string, double> category1_category2_to_score; string company1_id_company2_id = get_company_pair_key(ref product1, ref product2); if (!company1_id_company2_id_to_category1_category2_to_score.TryGetValue(company1_id_company2_id, out category1_category2_to_score)) { category1_category2_to_score = new Dictionary<string, double>(); company1_id_company2_id_to_category1_category2_to_score[company1_id_company2_id] = category1_category2_to_score; } double score; string category1_category2 = product1.DbProduct.Category + "=" + product2.DbProduct.Category; if (!category1_category2_to_score.TryGetValue(category1_category2, out score)) { score = get_category_comparison_score(product1, product2); category1_category2_to_score[category1_category2] = score; } return score; }
public ProductPair(Engine engine, Product product1, Product product2) { this.engine = engine; { CategoryScore = engine.CompanyPairs.GetCategoryComparisonScore(product1, product2); } { Dictionary<string, double> word2name_score = new Dictionary<string, double>(); foreach (string word in product1.Words(Field.Name)) { if (product2.Words2Count(Field.Name).ContainsKey(word)) word2name_score[word] = .5 * engine.Companies.Get(product1.DbProduct.CompanyId).WordWeight(Field.Name, word) + .5 * engine.Companies.Get(product2.DbProduct.CompanyId).WordWeight(Field.Name, word); } //MatchedWords[Field.Name] = word2name_score.Keys.ToList(); if (word2name_score.Count > 0) { NameScore = .5 * ((double)word2name_score.Values.Sum() / word2name_score.Count) + .25 * ((double)word2name_score.Count / product1.Words(Field.Name).Count) + .25 * ((double)word2name_score.Count / product2.Words(Field.Name).Count); } } // decimal p1 = product1.DbProduct.Price; //HashSet<string> matched_words = new HashSet<string>(); //foreach (string word in product1.Words(Field.Description)) //{ // if (product2.Word2Count(Field.Description).ContainsKey(word)) // matched_words.Add(word); //} //foreach (string word in matched_words) //{ // double score = get_word_score(word, product1, product2); // SecondaryScore += score; //} }
internal void MapCategoriesAndSave(Product product1, Product product2) { MapCategories(product1, product2); string company1_id_company2_id = get_company_pair_key(ref product1, ref product2); save_mapped_categories(company1_id_company2_id); }
string get_company_pair_key(ref Product product1, ref Product product2) { if (product1.DbProduct.CompanyId == product2.DbProduct.CompanyId) throw new Exception("Company cannot be mapped to iteslf.\r\nDd:" + product1.DbProduct.CompanyId); if (product1.DbProduct.CompanyId > product2.DbProduct.CompanyId) { Product p = product1; product1 = product2; product2 = p; } return product1.DbProduct.CompanyId + "," + product2.DbProduct.CompanyId; }
double get_category_comparison_score(Product product1, Product product2) { Dictionary<string, double> word2category_score = new Dictionary<string, double>(); foreach (string word in product1.Words(Field.Category)) { if (product2.Words2Count(Field.Category).ContainsKey(word)) word2category_score[word] = .5 * engine.Companies.Get(product1.DbProduct.CompanyId).WordWeight(Field.Category, word) + .5 * engine.Companies.Get(product2.DbProduct.CompanyId).WordWeight(Field.Category, word); } double score = 0; if (word2category_score.Count > 0) { score = .5 * ((double)word2category_score.Values.Sum() / word2category_score.Count) + .25 * ((double)word2category_score.Count / product1.Words(Field.Category).Count) + .25 * ((double)word2category_score.Count / product2.Words(Field.Category).Count); } score = (do_categories_belong2mapped_ones(product1, product2) ? 1 : 0.3) * score; return score; }
bool do_categories_belong2mapped_ones(Product product1, Product product2) { Dictionary<string, HashSet<string>> category1s_to_mapped_category2s; string company1_id_company2_id = get_company_pair_key(ref product1, ref product2); if (!company1_id_company2_id_to_category1s_to_mapped_category2s.TryGetValue(company1_id_company2_id, out category1s_to_mapped_category2s)) { var category1s_to_mapped_category2s_ = Cliver.Bot.DbSettings.Get<Dictionary<string, List<string>>>(engine.Dbc, SettingsKey.SCOPE, SettingsKey.CATEGORY_MAP + company1_id_company2_id); if (category1s_to_mapped_category2s_ != null) { category1s_to_mapped_category2s = new Dictionary<string, HashSet<string>>(); foreach (string c1 in category1s_to_mapped_category2s_.Keys) category1s_to_mapped_category2s[c1] = new HashSet<string>(category1s_to_mapped_category2s_[c1]); } else category1s_to_mapped_category2s = null; company1_id_company2_id_to_category1s_to_mapped_category2s[company1_id_company2_id] = category1s_to_mapped_category2s; } if (category1s_to_mapped_category2s == null) return false; HashSet<string> mapped_category2s; foreach(string c1 in category1s_to_mapped_category2s.Keys) if (is_child_of_category(product1.DbProduct.Category, c1)) if (category1s_to_mapped_category2s.TryGetValue(c1, out mapped_category2s)) foreach(string c2 in mapped_category2s) if (is_child_of_category(product2.DbProduct.Category, c2)) return true; return false; }
internal void UnmapCategoriesAndSave(Product product1, Product product2) { Dictionary<string, HashSet<string>> category1s_to_mapped_category2s; string company1_id_company2_id = get_company_pair_key(ref product1, ref product2); if (!company1_id_company2_id_to_category1s_to_mapped_category2s.TryGetValue(company1_id_company2_id, out category1s_to_mapped_category2s)) return; HashSet<string> category2s; if (!category1s_to_mapped_category2s.TryGetValue(product1.DbProduct.Category, out category2s)) return; category2s.Remove(product2.DbProduct.Category); if (category2s.Count < 1) category1s_to_mapped_category2s.Remove(product1.DbProduct.Category); save_mapped_categories(company1_id_company2_id); }
internal Company Get(Product product) { return Get(product.DbProduct.CompanyId); }
internal void Ininitalize(ICollection<Fhr.ProductOffice.Models.Product> products) { foreach (Fhr.ProductOffice.Models.Product product in products) { if (product == null) throw new Exception("product is null"); Product p = null; if (!product_ids2Product.TryGetValue(product.Id, out p)) { p = new Product(engine, product); product_ids2Product[product.Id] = p; } } }
internal Product[] GetLinked(int link_id) { List<Product> ps = new List<Product>(); foreach (Fhr.ProductOffice.Models.Product product in engine.Db.Products.Where(p => p.LinkId == link_id)) { Product p = null; if (!product_ids2Product.TryGetValue(product.Id, out p)) { p = new Product(engine, product); product_ids2Product[product.Id] = p; } ps.Add(p); } return ps.ToArray(); }