/// <summary> /// Generates a single row of products for the tree, given the list of parent product ids /// </summary> /// <param name="parentProductIdentifiers">the list of parent products for which a number of child products has to be generated</param> /// <param name="breadthPerLevel">the number of child products that have to be generated per parent product</param> /// <returns>a list of the id's of the child products that have been created</returns> private List <int> GenerateProductRowAndRelations(int[] parentProductIdentifiers, int breadthPerLevel) { List <int> childProductsCreated = new List <int>(); for (int i = 0; i < parentProductIdentifiers.Length; i++) { for (int j = 0; j < breadthPerLevel; j++) { int childProductId; // first insert the product using (ISession session = connector.Connection.Session()) { // string statement = "CREATE (n:Product { name: 'Product #c" + (chainId + 1) + "-p" + (i + 1) + "-p" + (j + 1) + "' }) RETURN ID(n) AS id"; string statement = InsertProduct(false, parentProductIdentifiers[i] * 2 + j); IStatementResult res = session.WriteTransaction(tx => tx.Run(statement)); IRecord record = res.Peek(); childProductId = record["id"].As <int>(); } // add it to the products created list childProductsCreated.Add(childProductId); // then create the relation for the product hierarchy using (ISession session = connector.Connection.Session()) { string statement = "MATCH (p:Product), (c:Product)" + " WHERE ID(p) = " + parentProductIdentifiers[i] + " AND ID(c) =" + childProductId + " CREATE (p)-[:CONSISTS_OF]->(c)"; session.WriteTransaction(tx => tx.Run(statement)); } } } return(childProductsCreated); }
/// <summary> /// Generates one product tree, to be used with a single thread of the multi-threaded way of generating product trees /// </summary> /// <param name="data">ProductTree data</param> private void mt_GenerateProductTree(object data) { ProductTreeData d = (ProductTreeData)data; int topLevelId = 0; // generate the top level product using (ISession session = connector.Connection.Session()) { //string statement = "CREATE (n:Product { name: 'TopLevelProduct #o" + (i + 1) + "-p" + (j + 1) + "' }) RETURN ID(n) AS id"; string statement = InsertProduct(true, d.orgIter * d.productsPerSupplier + d.prodIter); IStatementResult res = session.WriteTransaction(tx => tx.Run(statement)); IRecord record = res.Peek(); topLevelId = record["id"].As <int>(); } // add the top level product to the top level supplier using (ISession session = connector.Connection.Session()) { string statement = "MATCH (p:Product), (o:Organization), (l:Location)" + " WHERE ID(p) = " + topLevelId + " AND ID(o) = " + d.org + " AND ID(l) = " + d.locationId + " CREATE (o)-[:PERFORMS]->(a:Activity " + InsertActivity(d.orgIter) + ")," + " (a)-[:PRODUCES]->(p)," + " (a)-[:LOCATED_AT]->(l)" + " MERGE (o)-[:HAS_LOCATION]->(l)"; IStatementResult res = session.WriteTransaction(tx => tx.Run(statement)); } List <int> previousResults = new List <int>(); // for the depth of the chain for (int k = 0; k < d.depth; k++) { // in the first pass, generate the products for our top level product if (k == 0) { previousResults.Add(topLevelId); previousResults = GenerateProductRowAndRelations(previousResults.ToArray(), d.breadthPerLevel); } // in subsequent passes, take the previous row of products and generate a new underlying row for all of them else { previousResults = GenerateProductRowAndRelations(previousResults.ToArray(), d.breadthPerLevel); } } }
/// <summary> /// Generates a set number of organizations; they can be located anwywhere in the chain /// </summary> /// <param name="organizations">The number of organiations</param> /// <returns>a list of generated organization ids</returns> private int[] GenerateOrganizations(int organizations) { List <int> result = new List <int>(); var watch = System.Diagnostics.Stopwatch.StartNew(); using (ISession session = connector.Connection.Session()) { for (int i = 0; i < organizations; i++) { string statement = InsertOrganization(false, i); IStatementResult res = session.WriteTransaction(tx => tx.Run(statement)); IRecord record = res.Peek(); int id = record["id"].As <int>(); result.Add(id); } } watch.Stop(); Logger.Info("Added organizations in " + watch.ElapsedMilliseconds + "ms" + "(" + (watch.ElapsedMilliseconds / 1000) + "s)"); return(result.ToArray()); }
public override RawRecord Peek() => new Neo4jRawRecord(Result.Peek());
/// <summary> /// Generates all of the product trees necessary (amount of top level suppliers * amount of products) /// starts with the top level products, and then proceeds with all branches in the tree /// </summary> /// <param name="organizationIdentifiers">The id's of the top level organizations</param> /// <param name="productsPerSupplier">The number of products each supplier should get</param> /// <param name="depth">The depth of each chain (in how many branches does each product split up)</param> /// <param name="breadthPerLevel">The breadth of each chain per level; the number of products to generate for the product above</param> /// <param name="locations">The location ids to be used</param> private void GenerateProductTrees(int[] organizationIdentifiers, int productsPerSupplier, int depth, int breadthPerLevel, int[] locationIdentifiers) { var watchTotal = System.Diagnostics.Stopwatch.StartNew(); // for each top level supplier for (int i = 0; i < organizationIdentifiers.Length; i++) { Logger.Debug("Generating for Organization: " + (i + 1)); // for each of their products for (int j = 0; j < productsPerSupplier; j++) { var watch = System.Diagnostics.Stopwatch.StartNew(); int topLevelId = 0; // generate the top level product using (ISession session = connector.Connection.Session()) { //string statement = "CREATE (n:Product { name: 'TopLevelProduct #o" + (i + 1) + "-p" + (j + 1) + "' }) RETURN ID(n) AS id"; string statement = InsertProduct(true, i * productsPerSupplier + j); IStatementResult res = session.WriteTransaction(tx => tx.Run(statement)); IRecord record = res.Peek(); topLevelId = record["id"].As <int>(); } // add the top level product to the top level supplier using (ISession session = connector.Connection.Session()) { string statement = "MATCH (p:Product), (o:Organization), (l:Location)" + " WHERE ID(p) = " + topLevelId + " AND ID(o) = " + organizationIdentifiers[i] + " AND ID(l) = " + locationIdentifiers[i] + " CREATE (o)-[:PERFORMS]->(a:Activity " + InsertActivity(i) + ")," + " (a)-[:PRODUCES]->(p)," + " (a)-[:LOCATED_AT]->(l)" + " MERGE (o)-[:HAS_LOCATION]->(l)"; IStatementResult res = session.WriteTransaction(tx => tx.Run(statement)); IRecord record = res.Peek(); } List <int> previousResults = new List <int>(); // for the depth of the chain for (int k = 0; k < depth; k++) { // in the first pass, generate the products for our top level product if (k == 0) { previousResults.Add(topLevelId); previousResults = GenerateProductRowAndRelations(previousResults.ToArray(), breadthPerLevel); } // in subsequent passes, take the previous row of products and generate a new underlying row for all of them else { previousResults = GenerateProductRowAndRelations(previousResults.ToArray(), breadthPerLevel); } } watch.Stop(); Logger.Info("Took " + watch.ElapsedMilliseconds + "ms " + "(" + (watch.ElapsedMilliseconds / 1000) + "s) " + "to generate products and relations for product " + (j + 1) + " for organisation " + (i + 1)); } } watchTotal.Stop(); Logger.Info("Took " + watchTotal.ElapsedMilliseconds + "ms " + "(" + (watchTotal.ElapsedMilliseconds / 1000) + "s) in total"); }