Generate Nested List (Tree) from Flat List - java

I have a plain class named MenuModel in Java (it's for nested menu as the name suggests) like this:
public class MenuModel {
public String id;
public String parentId = null;
public String title;
public MenuModel parent = null;
public List<MenuModel> children = new ArrayList<MenuModel>();
}
My code fetch data from web API and generate a flat list of MenuModel with only id, parentId, and title fields filled with data. However, I need each MenuModel to have references to its parent and (optionally) children for further uses.
I have thought of a method which make a nested loop to pair the models each other and check if they are parent and child. But I think that costs too much (n^2 or n^3 complexity, the itemset is large) and can only fill the parent field.
What is the best way to achieve this in Java? To summarize:
Input: ArrayList<MenuModel> source
Output: ArrayList<MenuModel> result containing all MenuModel from source which has parentId = null (that means, it's top level menu), with each MenuModel has children fields filled with reference to their respective children MenuModel. Additionally, each children have reference to their parents.
Thanks in advance

Go through all the records and add them to a HashMap<String, MenuModel> (the key being the ID).
Then, for each record record:
Look up the parent ID in the above map to get parent.
Assign the parent to this record's parent variable - record.parent = parent.
Add this record to the parent's list of children - parent.children.add(record).
Running time: Expected O(n).

Related

To Implement Parent/Child & get Set of records If i give parent name

I have data as shown as below. Here if Team 1 is parent & having 2 child Team A & Team B. Team A is again a parent & having player names as child. Team B does not have any child.
Again in another scenario, Team A is independent parent & contains some child etc..
If i give Team 1, then it should fetch records of Team A & Team B as a bundle.
If i give Team A, then it should fetch records of Team A containing its child.
I was thinking to implement this using Map or Tree . and I tried this -
public class Node {
private String id;
private List<Node> children = new ArrayList<>();
private Node parent;
..........
//setters and getters
}
but here creating node dynamically is problem because we don't know the levels of parents(in this example there are 2). means "Dhoni" again contains some child like wise.
How to implements this ?. Please guide.
Whatever i understood from problem description i will try to summarize here.You are looking for a data structure which can take parent name(key) and it might have children, and each child also further can be extended.
public class Node {
private String id; // for each level you have key defined.
private List<Node> children = new ArrayList<>(); //using given key you can get children list
}
You can use map here
Map<String, List<Node>> // here key is team name etc., and list represents children.
If you give team1 as key, you get list which contains teamA, teamB. So if you want to check further, check list size, if it is greater than zero, you can get children(Further you can get all the players defined for both teamA,teamB) otherwise you are at last child.

querydsl over collections In clause

I'm using querydsl over collections.
I'm trying to get all the elements that are contained in another list.
public class Parent {
private List<Child>;
}
public class Child {
private String key;
private String value;
}
Due a concrete list of Child objects (List<Child> lovedChilds), for each parent I need to select those childs are included in lovedChilds.
List<Parent> parents = ...;
for (Parent parent in parents)
{
select
from (child, parent.childs)
where lovedChilds contains a lovedChild
where child.getKey.equals(lovedChild.getKey);
}
Since you have an n:m relation you should have a cross table somewhere.
I asume it to be parent2child with the columns parent and child (foreign keys to the corresponding ID columns).
Simply perform a join:
select * from parent join parent2child join child where child.key in lovedChildren
If you want to get the parent objects only once, you can add a group by or a distinct.

data modeling in spring-data-neo4j

My graph contains nodes called points and lines.
There is a relationship type called "NEXT", which connects two points and has a property called lineID (a long). A line node consists simply of an ID and a reference to a "root" point. To traverse a line is to start with its root node and follow the NEXT relationships whose lineID matches the id of the line being traversed. To clarify, if we're traversing a line with ID 123, whose root point has id 321, the Cypher traversal would be:
START n = node(321)
MATCH (n)-[rel:NEXT*{lineID:123}]->(x)
RETURN collect(rel)
A line, then, is essentially a linked list of Next relationships with matching lineID properties. That said, I don't want to persist this list as a property of lines - I want the list to be constructed by a traversal when a line is loaded.
What are my options for implementing this in spring-data-neo4j? Specifically, should "lines" exist as NodeEntitys, and if so what should they contain?
#NodeEntity
class Line {
#RelatedTo(type="ROOT")
Point root;
#RelatedToVia(type="NEXT")
Iterable<Item> list;
doesn't quite fit, because the line is not related via Next relationships to the item, the root point is. It also fails to address the fact that those NEXT relationships need to have a lineID property matching the line's ID (which becomes important because some points exist on multiple lines - i.e. they have multiple NEXT relationships with different lineID's). I have a hunch that the solution will involve annotating the list as a #GraphTraversal, but I don't understand how that would work.
I'm doing this largely as an exercise to wrap my head around data modeling in SDN, in the context of wrapping my head around Neo4j and graph databases in general. If the question I'm asking reveals a flaw in my understanding of any of these things, I'd be very appreciative if someone could point it out.
This should be a suitable model for your entities:
#NodeEntity
class Point {
#GraphId
protected Long id;
#RelatedToVia(type="NEXT")
Set<Edge> edges;
}
#NodeEntity
class Line {
#GraphId
protected Long id;
#RelatedTo(type="ROOT")
Point root;
}
#RelationshipEntity
public class Edge {
#GraphId
protected Long id;
#StartNode private Point from;
#EndNode private Point to;
#RelatedTo(type="LINE")
Line line;
}
It easily allows both programmatic navigation in Java as in:
Set edges = line.getPoint().getEdges();
for (Edge edge: edges) {
if (edge.getLine().getId() == id) {
...
}
}
or Cypher queries like the one you listed.

Query on array property or embedded property

consider following classes:
class Basic{
String id;
Double val;
//some other member variables
}
class NodeBO{
List<String> id;
Type type;
// list of id from objects of Basic class in data below
Map<ChEnum, Basic> data;
addBeans(NodeBO nodeBO, Node node){
// in transaction...
node.setProperty("priperties", nodeBO.toString());
// is it ok to convert to array? or should be converted to JSON string?
node.setProperty(GraphElementProps.id,toArray(nodeBO.id));
node.setProperty(GraphElementProps.type, nodeBO.type);
}
#override
toString(){
//return json of this object
}
}
enum ChEnum{
CH1(1), CH2(2);
// constructor and some methods
}
nodes are indexed using autoIndexer:
AutoIndexer<Node> nodeAutoIndexer = GRAPH_DB.index().getNodeAutoIndexer();
nodeAutoIndexer.startAutoIndexingProperty(GraphElementProps.id);
nodeAutoIndexer.setEnabled(true);
GRAPH_NODE_AUTO_INDEX = nodeAutoIndexer.getAutoIndex();
Here I'm storing GraphElementProps.id as node property (by converting to array). Does it take array (of string) as property? Or should I convert list to JSON-string and then store?
I want to be able to query on this array given with queryId. e.g. query on node-index to get nodes in which node.getProperty(GraphElementProps.id) contain given queryId? i.e. something like:
// how to do this?
GRAPH_NODE_AUTO_INDEX.get(/*Nodes whose id contain queryId*/);
Or is it (somehow) possible to make id property of Basic class indexable and searchable? How to index such properties, if possible? and how to query them?
I'm unable to understand but is it something related to Spring-data-neo4j? I'm completely new to Spring-data-neo4j.
I think the best solution is to use Spring-data-neo4j. This will allow to index embedded fields and query on them.

Hibernate: updating child object

I have such structure:
// all objects have valid mapping to database
public class Child {
private int id;
private String name;
}
public class Parent {
private int id;
private String name;
private List<Child> chidlren;
}
and I have to update specific child B inside parent A.
There are two ways:
Update child's fields inside collection and update the whole object:
Parent temp = dao.getParent(id);
temp.getChildren.get(0).setName('test');
dao.updateParent(temp);
Update only child object:
Child temp = dao.getChild(id);
temp.setName('test');
dao.updateChild(temp);
Which one is better if I want to get more perfomance?
Thank you
On the surface, I would surmise that the second solution
2.Update only child object
would be more performant.
However, the only way you determine this quantitatively would be to turn on Hibernate's show_sql, capture the SQL for Solution 1 and Solution 2, run an Explain Plan for each of your solutions, and compare the resulting Explain Plans.
You could get differing results depending on what else has changed/not changed in the Parent object and other children in the Parent.children collection. When capturing SQL for Explain Plans, you would want to try different scenarios.

Categories

Resources