private void CreatIngredientUsageVertices(IModelerLoader loader) { // Loop through ingredient usages and fill in vertices on graph // For each item: Create IngredientUsage and add to recipe, create IngredientNode (if necessary) and add recipe to IngredientNode foreach (var o in loader.LoadIngredientGraph()) { var recipeId = o.RecipeId; var ingredientId = o.IngredientId; var qty = o.Qty; var unit = o.Unit; var convType = Unit.GetConvertionType(unit); List<RecipeNode>[] nodes; IngredientNode ingredientNode; var node = this.snapshot.recipeMap[recipeId]; // New ingredient, create node for it if (!this.snapshot.ingredientMap.TryGetValue(ingredientId, out ingredientNode)) { nodes = new List<RecipeNode>[RecipeTag.NumberOfTags]; ingredientNode = new IngredientNode() { IngredientId = ingredientId, RecipesByTag = nodes, ConversionType = convType }; this.snapshot.ingredientMap.Add(ingredientId, ingredientNode); } else { nodes = ingredientNode.RecipesByTag as List<RecipeNode>[]; } // For each tag the recipe has, we need to create a link through ingNode.RecipesByTag to the recipe // Don't Index Hidden recipes if (!node.Hidden) { foreach (var tag in node.Tags) { if (nodes[tag.Value] == null) { nodes[tag.Value] = new List<RecipeNode>(); } // Add ingredient link to RecipeNode nodes[tag.Value].Add(node); } } // Add ingredient usage to recipe var usages = node.Ingredients as List<IngredientUsage>; usages.Add(new IngredientUsage() { Amount = qty, Ingredient = ingredientNode, Unit = unit }); } }
public void Index(IKPCContext context) { var timer = new Stopwatch(); timer.Start(); ratingGraph = new RatingGraph(); var loader = context.ModelerLoader; foreach (var dataItem in loader.LoadRatingGraph()) { var r = dataItem.Rating; var uid = dataItem.UserId; var rid = dataItem.RecipeId; if (r < 4) //Rating too low to worry about { continue; //TODO: Might not be needed, DB should only query for 4 or 5 star ratings } ratingGraph.AddRating(r, uid, rid); } ModelingSession.Log.InfoFormat("Building Rating Graph took {0}ms.", timer.ElapsedMilliseconds); timer.Reset(); timer.Start(); //Create empty recipe nodes without links snapshot.recipeMap = (from o in loader.LoadRecipeGraph() select new RecipeNode() { RecipeId = o.Id, Rating = o.Rating, Tags = o.Tags, Hidden = o.Hidden, Ingredients = new List <IngredientUsage>() }).ToDictionary(k => k.RecipeId); ModelingSession.Log.InfoFormat("Building empty RecipeNodes took {0}ms.", timer.ElapsedMilliseconds); timer.Reset(); timer.Start(); //Build tag index foreach (var r in snapshot.recipeMap.Values) { if (r.Hidden) { continue; //_recipeList does not include Hidden recipes so they don't get picked at random } foreach (var tag in r.Tags) { var nodes = snapshot.recipeList[tag.Value] as List <RecipeNode>; if (nodes == null) { snapshot.recipeList[tag.Value] = nodes = new List <RecipeNode>(); } nodes.Add(r); } } for (var i = 0; i < snapshot.recipeList.Length; i++) { var list = snapshot.recipeList[i] as List <RecipeNode>; if (list != null) { snapshot.recipeList[i] = list.ToArray(); } else //No recipes in DB use this tag { snapshot.recipeList[i] = new RecipeNode[0]; } } ModelingSession.Log.InfoFormat("Indexing recipes by tag took {0}ms.", timer.ElapsedMilliseconds); timer.Reset(); timer.Start(); //Loop through ingredient usages and fill in vertices on graph //For each item: Create IngredientUsage and add to recipe, create IngredientNode (if necessary) and add recipe to IngredientNode foreach (var o in loader.LoadIngredientGraph()) { var rid = o.RecipeId; var ingid = o.IngredientId; var qty = o.Qty; var unit = o.Unit; var convType = Unit.GetConvType(unit); List <RecipeNode>[] nodes; IngredientNode ingNode; var node = snapshot.recipeMap[rid]; if (!snapshot.ingredientMap.TryGetValue(ingid, out ingNode)) //New ingredient, create node for it { nodes = new List <RecipeNode> [RecipeTag.NUM_TAGS]; snapshot.ingredientMap.Add(ingid, ingNode = new IngredientNode() { IngredientId = ingid, RecipesByTag = nodes, ConvType = convType }); } else { nodes = ingNode.RecipesByTag as List <RecipeNode>[]; } //For each tag the recipe has, we need to create a link through ingNode.RecipesByTag to the recipe if (!node.Hidden) //Don't index Hidden recipes { foreach (var tag in node.Tags) { if (nodes[tag.Value] == null) { nodes[tag.Value] = new List <RecipeNode>(); } nodes[tag.Value].Add(node); //Add ingredient link to RecipeNode } } var usages = node.Ingredients as List <IngredientUsage>; //Add ingredient usage to recipe usages.Add(new IngredientUsage() { Amt = qty, Ingredient = ingNode, Unit = unit }); } ModelingSession.Log.InfoFormat("Creating IngredientUsage vertices took {0}ms.", timer.ElapsedMilliseconds); timer.Reset(); timer.Start(); //Create suggestion links for each recipe foreach (var r in snapshot.recipeMap.Values) { r.Suggestions = (from s in ratingGraph.GetSimilarRecipes(r.RecipeId) select snapshot.recipeMap[s]).ToArray(); } ModelingSession.Log.InfoFormat("Building suggestions for each recipe took {0}ms.", timer.ElapsedMilliseconds); timer.Reset(); }