From 0e17ac0a33895802008096b0e33dd3b224c17ea6 Mon Sep 17 00:00:00 2001
From: Douwe <d.geurtjens@students.uu.nl>
Date: Fri, 12 Nov 2021 16:04:30 +0100
Subject: [PATCH] Hierarchy unit test fixed

---
 aql/convertQuery.go   |   7 +-
 aql/hierarchy.go      | 385 +++++++-------------------------
 aql/hierarchy_test.go | 495 +++++++++++++++++++++---------------------
 aql/newHierarchy.go   | 113 ----------
 entity/queryStruct.go |  16 +-
 realtest.json         |  10 +-
 6 files changed, 338 insertions(+), 688 deletions(-)
 delete mode 100644 aql/newHierarchy.go

diff --git a/aql/convertQuery.go b/aql/convertQuery.go
index e6d5368..28303d7 100644
--- a/aql/convertQuery.go
+++ b/aql/convertQuery.go
@@ -6,6 +6,7 @@ This program has been developed by students from the bachelor Computer Science a
 package aql
 
 import (
+	"encoding/json"
 	"errors"
 	"fmt"
 	"strconv"
@@ -66,6 +67,8 @@ func (s *Service) ConvertQuery(JSONQuery *entity.IncomingQueryJSON) (*string, er
 		}
 		fmt.Println("Next please!")
 	}
+	fuckshitprinter, _ := json.Marshal(tree)
+	fmt.Println(string(fuckshitprinter))
 	result := createQuery(JSONQuery, tree, topNode)
 	return result, nil
 }
@@ -97,8 +100,8 @@ func createQueryRecurse(JSONQuery *entity.IncomingQueryJSON, tree []entity.Tree,
 	for constraint := range newNode.Constraints {
 		output += createFilter(newNode.Constraints[constraint], fmt.Sprintf("e_%v", newNode.ID))
 	}
-	for constraint := range currentTree.Self.Rel.QueryConstraintStruct {
-		output += createFilter(currentTree.Self.Rel.QueryConstraintStruct[constraint], fmt.Sprintf("r%v", currentTree.Self.Rel.ID))
+	for constraint := range currentTree.Self.Rel.Constraints {
+		output += createFilter(currentTree.Self.Rel.Constraints[constraint], fmt.Sprintf("r%v", currentTree.Self.Rel.ID))
 	}
 	output += fmt.Sprintf("FILTER r%v._from == e_%v._id AND r%v._to == e_%v._id", currentTree.Self.Rel.ID, currentTree.Self.FromNode.ID, currentTree.Self.Rel.ID, currentTree.Self.ToNode.ID)
 	var subNames []string
diff --git a/aql/hierarchy.go b/aql/hierarchy.go
index 3ab3814..bdd6591 100644
--- a/aql/hierarchy.go
+++ b/aql/hierarchy.go
@@ -1,344 +1,113 @@
 package aql
 
 import (
-	"fmt"
-	"strconv"
-
 	"git.science.uu.nl/graphpolaris/query-conversion/entity"
 )
 
 // We use consts to define string to prevent typos
-/*
 const ENTITYSTRING = "entity"
 const RELATIONSTRING = "relation"
 const GROUPBYSTRING = "groupBy"
 const FILTERSTRING = "filter"
-*/
-var reldone map[int]bool
-var entdone map[int]bool
-var funcdone map[int]bool
-var relfuncdone map[int]bool
-var filterDone map[int]bool
-
-func search(JSONQuery *entity.IncomingQueryJSON, index int) []entity.PdictList {
-	var listoflists []entity.PdictList
-	listoflists = []entity.PdictList{}
-	reldone = make(map[int]bool)
-	entdone = make(map[int]bool)
-	funcdone = make(map[int]bool)
-	relfuncdone = make(map[int]bool)
-	filterDone = make(map[int]bool)
-	var s entity.PdictList
-	//printSlice(s)
-	//layercounter = 0
-
-	initent := makePdict(ENTITYSTRING, index)
 
-	s = append(s, initent)
-	listoflists = append(listoflists, s)
-	listoflists = entToRel(JSONQuery, listoflists, initent)
-
-	for i := range listoflists {
-		for j := range listoflists[i] {
-			fmt.Println(listoflists[i][j])
-		}
-		fmt.Println("")
+var relationdone map[int]bool
+
+func createHierarchy(JSONQuery *entity.IncomingQueryJSON) ([]entity.Tree, entity.QueryEntityStruct) {
+	var treeList []entity.Tree
+	relationdone = make(map[int]bool)
+	topNode := getTopNode(JSONQuery)
+	topTreeSelfTriple := getTripleFromNode(JSONQuery, topNode)
+	topTree := entity.Tree{
+		Self:     topTreeSelfTriple,
+		Parent:   -1,
+		Children: []int{},
 	}
-	fmt.Println(listoflists)
-	return listoflists
+	treeList = append(treeList, topTree)
+	treeListIndex := len(treeList) - 1
+	treeList = getChildrenFromTree(JSONQuery, treeList, treeListIndex, 0)
+	return treeList, topNode
 }
 
 /*
-relToEnt Get the entities connected to a relation and recursivly constructs part of the hierarchy
-Entities always get added IN FRONT OF their respective relation in the hierarchy
-	JSONQuery: *entity.IncomingQueryJSON, the query in JSON format
-	rel: pdict, the relation to find all connected entities for
+Get a entity that has only 1 relation attached an return its index
 */
-func relToEnt(JSONQuery *entity.IncomingQueryJSON, listoflists []entity.PdictList, rel entity.Pdict) []entity.PdictList {
-	var newlist entity.PdictList
-	layercounter := findCurrentLayer(listoflists, rel)
-	// Loop over all entities
-	// If an entity is already in the entdone dict we already added it to the hierarchy, so we don't have to add it again
-	// If an entity matches either the from or to in a relation we can add it to the newlist
-	for i := range JSONQuery.Entities {
-		if _, ok := entdone[i]; !ok {
-			if JSONQuery.Relations[rel.Pointer].FromID == i && JSONQuery.Relations[rel.Pointer].FromType == ENTITYSTRING {
-				fromentity := makePdict(ENTITYSTRING, i)
-				newlist = append(newlist, fromentity)
-			} else if JSONQuery.Relations[rel.Pointer].ToID == i && JSONQuery.Relations[rel.Pointer].ToType == ENTITYSTRING {
-				toentity := makePdict(ENTITYSTRING, i)
-				newlist = append(newlist, toentity)
+func getTopNode(JSONQuery *entity.IncomingQueryJSON) entity.QueryEntityStruct {
+	indexOfNodeToReturn := -1
+	for i, node := range JSONQuery.Entities {
+		connectionCount := 0
+		for _, relation := range JSONQuery.Relations {
+			if (relation.FromType == ENTITYSTRING && relation.FromID == node.ID) || (relation.ToType == ENTITYSTRING && relation.ToID == node.ID) {
+				connectionCount++
 			}
 		}
-	}
-	// This relation has found all its entities so we can set it's ID to true
-	reldone[rel.Pointer] = true
-	// If the newlist is empty, we can just skip the recursion
-	// This is effectively our base case
-	if len(newlist) != 0 {
-		// If our layercounter is equal to 0 we are in the first "layer" of the hierarchy
-		// Because we add the entities IN FRONT OF their respective relation we don't have to move the layercounter before prepending
-		// If our layercounter is not equal to 0 we lower the layercounter and then add each item to the newly selected layer
-		listoflists = aboveAppend(listoflists, layercounter, newlist)
-
-		// After getting a list of entities we can only go towards a list of relation
-		// So we recurse by calling EntToRel
-		for i := range newlist {
-			fmt.Println("EntToRel being called with index?: " + strconv.Itoa(newlist[i].Pointer))
-			listoflists = entToRel(JSONQuery, listoflists, newlist[i])
-
+		if connectionCount == 1 {
+			indexOfNodeToReturn = i
+			return JSONQuery.Entities[indexOfNodeToReturn]
 		}
 	}
-
-	return listoflists
-
+	return JSONQuery.Entities[indexOfNodeToReturn]
 }
 
-/*
-entToRel Get the relations connected to a entity and recursivly constructs part of the hierarchy
-Relation always get added BEHIND their respective entity in the hierarchy
-	JSONQuery: *entity.IncomingQueryJSON, the query in JSON format
-	ent: pdict, the entity to find all connected relations for
-*/
-func entToRel(JSONQuery *entity.IncomingQueryJSON, listoflists []entity.PdictList, ent entity.Pdict) []entity.PdictList {
-	var newlist entity.PdictList
-	layercounter := findCurrentLayer(listoflists, ent)
-	// Loop over all relations
-	// If a relation is already in the reldone dict we already added it to the hierarchy, so we don't have to add it again
-	// If a relation matches either the from or to with the entity we can add it to the newlist
-	for i := range JSONQuery.Relations {
-		if _, ok := reldone[i]; !ok {
-			if JSONQuery.Relations[i].FromID == ent.Pointer && JSONQuery.Relations[i].FromType == ENTITYSTRING {
-				rel := makePdict(RELATIONSTRING, i)
-				newlist = append(newlist, rel)
-			} else if JSONQuery.Relations[i].ToID == ent.Pointer && JSONQuery.Relations[i].ToType == ENTITYSTRING {
-				rel := makePdict(RELATIONSTRING, i)
-				newlist = append(newlist, rel)
-			}
-		}
-	}
-	// This entity has found all its relations so we can set it's ID to true
-	entdone[ent.Pointer] = true
-
-	if len(newlist) != 0 {
-		// If our layercounter is equal to the length of the hierarchy - 1 we are in the last "layer" of the hierarchy
-		// Because we add the relations BEHIND their respective entities we don't have to move the layercounter before appending
-		// TODO TAKE OUT UNNEEDED LAYERCOUNTER INCREMENTS AND DECREMENTS
-		// If our layercounter is any other value we increase the layercounter and then add each item to the newly selected layer
-		listoflists = belowAppend(listoflists, layercounter, newlist)
-
-		// After getting a list of relations we can only go towards a list of entities or a list of functions
-		// So we recurse by calling RelToEnt and RelToAllFunc
-		for i := range newlist {
-			fmt.Println("RelToEnt being called with index?: " + strconv.Itoa(newlist[i].Pointer))
-			listoflists = relToEnt(JSONQuery, listoflists, newlist[i])
-			fmt.Println("RelToAllFunc being called with index?: " + strconv.Itoa(newlist[i].Pointer))
-			listoflists = relToAllFunc(JSONQuery, listoflists, newlist[i])
-
+func getTripleFromNode(JSONQuery *entity.IncomingQueryJSON, node entity.QueryEntityStruct) entity.Triple {
+	var tripleToReturn entity.Triple
+	for _, relation := range JSONQuery.Relations {
+		// The initial node was our From so we set the Triple accordingly
+		// TODO
+		// If the To is not an entity we might have to do something different
+		if (relation.FromType == ENTITYSTRING && relation.FromID == node.ID) && relation.ToType == ENTITYSTRING {
+			tripleToReturn.FromNode = node
+			tripleToReturn.Rel = relation
+			tripleToReturn.ToNode = JSONQuery.Entities[relation.ToID]
+		} else if (relation.ToType == ENTITYSTRING && relation.ToID == node.ID) && relation.FromType == ENTITYSTRING {
+			tripleToReturn.FromNode = JSONQuery.Entities[relation.ToID]
+			tripleToReturn.Rel = relation
+			tripleToReturn.ToNode = node
 		}
 	}
-	return listoflists
+	relationdone[tripleToReturn.Rel.ID] = true
+	return tripleToReturn
 }
 
-/*
-relToAllFunc Get the functions connected (both functions that are applied to a subquery a relation is a part of and functions the relation is connected to itself)
- to a relation and recursivly constructs part of the hierarchy
-If a function is applied to a subquery the relation is a part of, we add it BEHIND its respective relation
-If a function is connected to a relation (relation uses the results from the function), we add it IN FRONT OF its respective relation
-	JSONQuery: *entity.IncomingQueryJSON, the query in JSON format
-	rel: pdict, the relation to find all connected functions for
-*/
-func relToAllFunc(JSONQuery *entity.IncomingQueryJSON, listoflists []entity.PdictList, rel entity.Pdict) []entity.PdictList {
-	var funcappliedtosubquery entity.PdictList
-	var functowhichrelapplies entity.PdictList
-	layercounter := findCurrentLayer(listoflists, rel)
-	// Loop over all functions
-	// If a relation is already in the relfuncdone dict we already added it to the hierarchy, so we don't have to add it again
-	// If a function's relationID matches the current relation then the function is applied to a subquery
-	// If the relation's functionpointer matches a function's ID then the relation is connected to the function
-	// Depending on the case they get put in a different list and are put in different places in the hierarchy
-	for i := range JSONQuery.GroupBys {
-		if _, ok := relfuncdone[rel.Pointer]; !ok {
-			if _, ok := funcdone[i]; !ok {
-				if JSONQuery.GroupBys[i].RelationID == rel.Pointer {
-					relfunc := makePdict(GROUPBYSTRING, i)
-					funcappliedtosubquery = append(funcappliedtosubquery, relfunc)
-					fmt.Println("I AM HERE 1")
-				}
-
-				if JSONQuery.Relations[rel.Pointer].FromID == i && JSONQuery.Relations[rel.Pointer].FromType == GROUPBYSTRING {
-					fromfunc := makePdict(GROUPBYSTRING, i)
-					functowhichrelapplies = append(functowhichrelapplies, fromfunc)
-					fmt.Println("I AM HERE 2")
-
-				} else if JSONQuery.Relations[rel.Pointer].ToID == i && JSONQuery.Relations[rel.Pointer].ToType == GROUPBYSTRING {
-					tofunc := makePdict(GROUPBYSTRING, i)
-					functowhichrelapplies = append(functowhichrelapplies, tofunc)
-					fmt.Println("I AM HERE 3")
-
-				}
-
-			}
-		}
-
-	}
-	relfuncdone[rel.Pointer] = true
-	layercountertwo := layercounter
-	layercounterthree := layercounter
-	// See main function comment to see which sublist gets put where in the hierarchy
-	if len(functowhichrelapplies) != 0 {
-		listoflists = aboveAppend(listoflists, layercountertwo, functowhichrelapplies)
-
-		for i := range functowhichrelapplies {
-			fmt.Println("FuncToAllRell being called with index?: " + strconv.Itoa(functowhichrelapplies[i].Pointer))
-			listoflists = funcToAllRel(JSONQuery, listoflists, functowhichrelapplies[i])
-
-		}
-	}
-
-	if len(funcappliedtosubquery) != 0 {
-		//newlayercounter := layercounter
-		listoflists = belowAppend(listoflists, layercounterthree, funcappliedtosubquery)
-
-		for i := range funcappliedtosubquery {
-			fmt.Println("FuncToAllRel being called with index?: " + strconv.Itoa(funcappliedtosubquery[i].Pointer))
-			listoflists = funcToAllRel(JSONQuery, listoflists, funcappliedtosubquery[i])
-		}
-	}
-	return listoflists
+func getTripleFromRelation(JSONQuery *entity.IncomingQueryJSON, relation entity.QueryRelationStruct) entity.Triple {
+	var tripleToReturn entity.Triple
+	tripleToReturn.FromNode = JSONQuery.Entities[relation.FromID]
+	tripleToReturn.Rel = relation
+	tripleToReturn.ToNode = JSONQuery.Entities[relation.ToID]
+	return tripleToReturn
 }
 
-/*
-funcToAllRel Get the relations connected (both relations that are in a subquery a function is applied to and relations that are connected to the function itself)
- to a function and recursivly constructs part of the hierarchy
-If a relation is in a subquery that the function is applied to, we add the relation IN FRONT OF its respective function
-If a relation is connected to a function, we add the relation BEHIND its respective function
-	JSONQuery: *entity.IncomingQueryJSON, the query in JSON format
-	function: pdict, the function to find all connected relations for
-*/
-func funcToAllRel(JSONQuery *entity.IncomingQueryJSON, listoflists []entity.PdictList, function entity.Pdict) []entity.PdictList {
-	var funcappliedtosubquery entity.PdictList
-	var relattachedtofunc entity.PdictList
-	layercounter := findCurrentLayer(listoflists, function)
-	for i := range JSONQuery.Relations {
-		if _, ok := funcdone[function.Pointer]; !ok {
-			if _, ok := relfuncdone[i]; !ok {
-				// The func is attached to this relation
-				if JSONQuery.GroupBys[function.Pointer].RelationID == i {
-					funcrel := makePdict(RELATIONSTRING, i)
-					funcappliedtosubquery = append(funcappliedtosubquery, funcrel)
-
-				}
-
-				if JSONQuery.Relations[i].FromID == function.Pointer && JSONQuery.Relations[i].FromType == GROUPBYSTRING {
-					fromrel := makePdict(RELATIONSTRING, i)
-					relattachedtofunc = append(relattachedtofunc, fromrel)
-
-				} else if JSONQuery.Relations[i].ToID == function.Pointer && JSONQuery.Relations[i].ToType == GROUPBYSTRING {
-					torel := makePdict(RELATIONSTRING, i)
-					relattachedtofunc = append(relattachedtofunc, torel)
-
-				}
-
+func getChildrenFromTree(JSONQuery *entity.IncomingQueryJSON, treeList []entity.Tree, treeListIndex int, parentIndex int) []entity.Tree {
+	var childRelationTriples []entity.Triple
+	for i, relation := range JSONQuery.Relations {
+		// We found a relation that is not our parent relation so we can check if it matches on of our nodes
+		// If it matches one of the nodes we can add it
+		if _, ok := relationdone[i]; !ok {
+			if relation.FromType == ENTITYSTRING && relation.FromID == treeList[parentIndex].Self.FromNode.ID {
+				triple := getTripleFromRelation(JSONQuery, relation)
+				childRelationTriples = append(childRelationTriples, triple)
+				relationdone[i] = true
+			} else if relation.ToType == ENTITYSTRING && relation.ToID == treeList[parentIndex].Self.ToNode.ID {
+				triple := getTripleFromRelation(JSONQuery, relation)
+				childRelationTriples = append(childRelationTriples, triple)
+				relationdone[i] = true
 			}
 		}
 	}
-	funcdone[function.Pointer] = true
-
-	layercountertwo := layercounter
-	layercounterthree := layercounter
-	if len(funcappliedtosubquery) != 0 {
-		//newlayercounter := layercounter
-		listoflists = aboveAppend(listoflists, layercountertwo, funcappliedtosubquery)
-
-		for i := range funcappliedtosubquery {
-			fmt.Println("RelToEnt being called with index?: " + strconv.Itoa(funcappliedtosubquery[i].Pointer))
-			listoflists = relToEnt(JSONQuery, listoflists, funcappliedtosubquery[i])
-			fmt.Println("RelToAllFunc being called with index?: " + strconv.Itoa(funcappliedtosubquery[i].Pointer))
-			listoflists = relToAllFunc(JSONQuery, listoflists, funcappliedtosubquery[i])
-
-		}
-	}
-
-	if len(relattachedtofunc) != 0 {
-		listoflists = belowAppend(listoflists, layercounterthree, relattachedtofunc)
-
-		for i := range relattachedtofunc {
-			fmt.Println("RelToEnt being called with index?: " + strconv.Itoa(relattachedtofunc[i].Pointer))
-			listoflists = relToEnt(JSONQuery, listoflists, relattachedtofunc[i])
-			fmt.Println("RelToAllFunc being called with index?: " + strconv.Itoa(relattachedtofunc[i].Pointer))
-			listoflists = relToAllFunc(JSONQuery, listoflists, relattachedtofunc[i])
-		}
-	}
-	return listoflists
-}
-
-// A function that appends 1 level above (if index is 0 this won't work)
-func aboveAppend(listoflists []entity.PdictList, index int, values entity.PdictList) []entity.PdictList {
-	if index == 0 {
-		return prepend(listoflists, values)
-	} else {
-		index--
-		for i := range values {
-			listoflists[index] = append(listoflists[index], values[i])
-		}
-		return listoflists
-	}
-
-}
-
-// A function that appends 1 level below
-func belowAppend(listoflists []entity.PdictList, index int, values entity.PdictList) []entity.PdictList {
-	if index == len(listoflists)-1 {
-		listoflists = append(listoflists, values)
-		return listoflists
-
-	} else {
-		index++
-		for i := range values {
-			listoflists[index] = append(listoflists[index], values[i])
-		}
-		return listoflists
-
-	}
-}
-
-// A simple double-for loop that finds the layer in which an element resides in the hierarchy
-// Because we only append elements relative to another element, we can freely use this to keep track of layers
-func findCurrentLayer(list []entity.PdictList, element entity.Pdict) int {
-	currlayer := -1
-	for i, sublist := range list {
-		for j := range sublist {
-			if sublist[j].Pointer == element.Pointer && sublist[j].Typename == element.Typename {
-				currlayer = i
-				//break
+	// We now have all our children, so we can now make those trees and find their children
+	// We can now also add the indices to the list of children from the tree calling this function
+	if len(childRelationTriples) != 0 {
+		for _, triple := range childRelationTriples {
+			childTree := entity.Tree{
+				Self:     triple,
+				Parent:   treeListIndex,
+				Children: []int{},
 			}
+			treeList = append(treeList, childTree)
+			// We get the new treeListIndex, which we can now add to the list of children from the tree calling this function
+			treeListIndex = len(treeList) - 1
+			treeList[parentIndex].Children = append(treeList[parentIndex].Children, treeListIndex)
+			treeList = getChildrenFromTree(JSONQuery, treeList, treeListIndex, treeListIndex)
 		}
 	}
-	return currlayer
-}
-
-// Adds a list of pdicts to the hierarchy, but IN FRONT OF the current layer
-// Only needed when a entire new list has to be inserted in front of the hierarcy
-// Prepending to existing layers can be done by decreasing the layercounter and appending
-// See XToY functions for example usage
-func prepend(list []entity.PdictList, element entity.PdictList) []entity.PdictList {
-	var dummylist entity.PdictList
-	dummy := makePdict("dummy", -1)
-	dummylist = append(dummylist, dummy)
-	list = append(list, dummylist)
-	copy(list[1:], list)
-	list[0] = element
-	return list
-}
-
-/*
-makePdict makes a pdict based on a typename and pointer
-*/
-func makePdict(typeName string, pointer int) entity.Pdict {
-	return entity.Pdict{
-		Typename: typeName,
-		Pointer:  pointer,
-	}
-
+	return treeList
 }
diff --git a/aql/hierarchy_test.go b/aql/hierarchy_test.go
index 4b5f5d2..f3c96f9 100644
--- a/aql/hierarchy_test.go
+++ b/aql/hierarchy_test.go
@@ -3,7 +3,7 @@ package aql
 import (
 	"encoding/json"
 	"fmt"
-	"sort"
+	"strings"
 	"testing"
 
 	"git.science.uu.nl/graphpolaris/query-conversion/entity"
@@ -17,316 +17,307 @@ func TestHierarchyBasic(t *testing.T) {
 		"return": {
 			"entities": [
 				0,
-				1
+				1,
+				2,
+				3,
+				4
 			],
 			"relations": [
-				0
-			],
-			"groupBys": []
+				0,
+				1,
+				2,
+				3
+			]
 		},
 		"entities": [
 			{
 				"name": "parliament",
-				"ID": 0
-			},
-			{
-				"name": "parties",
-				"ID": 1
-			}
-		],
-		"relations": [
-			{
 				"ID": 0,
-				"name": "member_of",
-				"depth": {
-					"min": 1,
-					"max": 1
-				},
-				"fromType": "entity",
-				"fromID": 0,
-				"toType": "entity",
-				"toID": 1
-			}
-		],
-		"groupBys": [],
-		"filters": [
-			{
-				"ID": 0,
-				"fromType": "entity",
-				"fromID": 0,
-				"toType": "relation",
-				"toID": 0,
-				"attribute": "age",
-				"value": "45",
-				"dataType": "number",
-				"matchType": "GT",
-				"inType": "",
-				"inID": -1
+				"constraints": [
+					{
+						"attribute": "name",
+						"value": "Geert",
+						"dataType": "string",
+						"matchType": "CONTAINS"
+					}
+				]
 			},
 			{
+				"name": "commissions",
 				"ID": 1,
-				"fromType": "relation",
-				"fromID": 0,
-				"toType": "relation",
-				"toID": 1,
-				"attribute": "isChairman",
-				"value": "45",
-				"dataType": "number",
-				"matchType": "GT",
-				"inType": "",
-				"inID": -1
-			}
-		],
-		"limit": 5000
-	}
-	`)
-
-	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
-	json.Unmarshal(query, &JSONQuery)
-	listoflists := search(&JSONQuery, 0)
-
-	// Assert that the result and the expected result are the same
-	correctResult := `[[{entity 0} {entity 1}] [{filter 0}] [{relation 0}] [{filter 1}]]`
-	assert.Equal(t, correctResult, fmt.Sprint(listoflists))
-}
-
-func TestHierarchyRandomStart(t *testing.T) {
-	// Setup for test
-	// Create query conversion service
-	query := []byte(`{
-		"return": {
-			"entities": [
-				0,
-				1
-			],
-			"relations": [
-				0
-			],
-			"groupBys": []
-		},
-		"entities": [
+				"constraints": []
+			},
+			{
+				"name": "parliament",
+				"ID": 2,
+				"constraints": []
+			},
 			{
 				"name": "parties",
-				"ID": 1
+				"ID": 3,
+				"constraints": [
+					{
+						"attribute": "seats",
+						"value": "10",
+						"dataType": "int",
+						"matchType": "LT"
+					}
+				]
 			},
-			
 			{
-				"name": "parliament",
-				"ID": 0
+				"name": "resolutions",
+				"ID": 4,
+				"constraints": [
+					{
+						"attribute": "date",
+						"value": "mei",
+						"dataType": "string",
+						"matchType": "CONTAINS"
+					}
+				]
 			}
 		],
+		"groupBys": [],
 		"relations": [
 			{
 				"ID": 0,
-				"name": "member_of",
+				"name": "part_of",
 				"depth": {
 					"min": 1,
 					"max": 1
 				},
 				"fromType": "entity",
-				"fromID": 0,
+				"fromId": 0,
 				"toType": "entity",
-				"toID": 1
-			}
-		],
-		"groupBys": [],
-		"filters": [
-			{
-				"ID": 0,
-				"fromType": "entity",
-				"fromID": 0,
-				"toType": "relation",
-				"toID": 0,
-				"attribute": "age",
-				"value": "45",
-				"dataType": "number",
-				"matchType": "GT",
-				"inType": "",
-				"inID": -1
-			},
-			{
-				"ID": 1,
-				"fromType": "relation",
-				"fromID": 0,
-				"toType": "relation",
 				"toID": 1,
-				"attribute": "isChairman",
-				"value": "45",
-				"dataType": "number",
-				"matchType": "GT",
-				"inType": "",
-				"inID": -1
-			}
-		],
-		"limit": 5000
-	}
-	`)
-
-	// Unmarshall the incoming message into an IncomingJSONQuery object
-	var JSONQuery entity.IncomingQueryJSON
-	json.Unmarshal(query, &JSONQuery)
-	correctResult := make([]entity.PdictList, 4)
-	correctResult[0] = entity.PdictList{{Typename: "entity", Pointer: 0}, {Typename: "entity", Pointer: 1}}
-	correctResult[1] = entity.PdictList{{Typename: "filter", Pointer: 0}}
-	correctResult[2] = entity.PdictList{{Typename: "relation", Pointer: 0}}
-	correctResult[3] = entity.PdictList{{Typename: "filter", Pointer: 1}}
-
-	for i := range JSONQuery.Entities {
-		listoflists := search(&JSONQuery, i)
-		sortedListOfLists := make([]entity.PdictList, len(listoflists))
-		for i, list := range listoflists {
-			k := make(entity.PdictList, list.Len())
-			copy(k, list)
-			sort.Sort(k)
-			sortedListOfLists[i] = k
-		}
-		assert.Equal(t, fmt.Sprint(correctResult), fmt.Sprint(sortedListOfLists))
-	}
-
-}
-
-func TestHierarchyWithGroupby(t *testing.T) {
-	// Setup for test
-	// Create query conversion service
-	query := []byte(`{
-		"return": {
-			"entities": [
-				0,
-				1,
-				2,
-				3
-			],
-			"relations": [
-				0,
-				1,
-				2
-			]
-		},
-		"entities": [
-			{
-				"ID": 0,
-				"name": "parliament"
+				"constraints": []
 			},
 			{
 				"ID": 1,
-				"name": "commissions"
-			},
-			{
-				"ID": 2,
-				"name": "parliament"
-			},
-			{
-				"ID": 3,
-				"name": "resolutions"
-			}
-		],
-		"relations": [
-			{
-				"type": "part_of",
+				"name": "part_of",
 				"depth": {
 					"min": 1,
 					"max": 1
 				},
 				"fromType": "entity",
-				"fromId": 0,
+				"fromId": 2,
 				"toType": "entity",
-				"toID": 1
-	   
+				"toID": 1,
+				"constraints": []
 			},
 			{
-				"type": "part_of",
+				"ID": 2,
+				"name": "member_of",
 				"depth": {
 					"min": 1,
 					"max": 1
 				},
-				"fromType": "groupBy",
-				"fromID": 0,
+				"fromType": "entity",
+				"fromId": 2,
 				"toType": "entity",
-				"toID": 2
-	   
+				"toID": 3,
+				"constraints": []
 			},
 			{
-				"type": "submits",
+				"ID": 3,
+				"name": "submits",
 				"depth": {
 					"min": 1,
 					"max": 1
 				},
 				"fromType": "entity",
-				"fromID": 2,
+				"fromId": 2,
 				"toType": "entity",
-				"toID": 3
+				"toID": 4,
+				"constraints": []
 			}
 		],
-		"groupBys": [
-			{
-				"ID": 0,
-				"groupType": "entity",
-				"groupID": 0,
-				"groupAttribute": "age",
-				"byType": "entity",
-				"byID": 1,
-				"byAttribute": "name",
-				"appliedModifier": "AVG",
-				"relationID": 0,
-				"constraints": [
-					{
-						"attribute": "age",
-						"value": "45",
-						"dataType": "number",
-						"matchType": "GT",
-						"functionPointer": {
-							"from": -1,
-							"to": -1
-						}
-			   
-					}
-				]
-			}
-		],
-		"filters": [
-			{
-				"ID": 0,
-				"fromType": "groupBy",
-				"fromID": 0,
-				"toType": "relation",
-				"toID": 1,
-				"attribute": "age",
-				"value": "45",
-				"dataType": "number",
-				"matchType": "GT",
-				"inType": "",
-				"inID": -1
-			}
-		],
-		"limit": 5000,
-		"modifiers": [],
-		"databaseName": "TweedeKamer"
+		"limit": 5000
 	}
 	`)
 
 	// Unmarshall the incoming message into an IncomingJSONQuery object
 	var JSONQuery entity.IncomingQueryJSON
 	json.Unmarshal(query, &JSONQuery)
-	correctResult := make([]entity.PdictList, 5)
-	correctResult[0] = entity.PdictList{{Typename: "entity", Pointer: 0}, {Typename: "entity", Pointer: 1}}
-	correctResult[1] = entity.PdictList{{Typename: "relation", Pointer: 0}}
-	correctResult[2] = entity.PdictList{{Typename: "entity", Pointer: 2}, {Typename: "entity", Pointer: 3}, {Typename: "groupBy", Pointer: 0}}
-	correctResult[3] = entity.PdictList{{Typename: "filter", Pointer: 0}}
-	correctResult[4] = entity.PdictList{{Typename: "relation", Pointer: 1}, {Typename: "relation", Pointer: 2}}
+	// Get the hierarchy and turn it into JSON so we can turn it into strings later
+	treeList, topNode := createHierarchy(&JSONQuery)
+	jsonTopNode, err := json.Marshal(topNode)
+	if err != nil {
+		fmt.Println("Marshalling went wrong")
+	}
+	jsonTreeList, err := json.Marshal(treeList)
+	if err != nil {
+		fmt.Println("Marshalling went wrong")
+	}
+	// These are the expected (correct) outputs
+	correctTopNode := []byte(`{"ID":0,"Name":"parliament","Constraints":[{"Attribute":"name","Value":"Geert","DataType":"string","MatchType":"CONTAINS","InID":0,"InType":""}]}`)
+	correctTreeList := []byte(`[
+		{
+			"Self": {
+				"FromNode": {
+					"ID": 0,
+					"Name": "parliament",
+					"Constraints": [
+						{
+							"Attribute": "name",
+							"Value": "Geert",
+							"DataType": "string",
+							"MatchType": "CONTAINS",
+							"InID": 0,
+							"InType": ""
+						}
+					]
+				},
+				"Rel": {
+					"ID": 0,
+					"Name": "part_of",
+					"FromType": "entity",
+					"FromID": 0,
+					"ToType": "entity",
+					"ToID": 1,
+					"Depth": {
+						"Min": 1,
+						"Max": 1
+					},
+					"Constraints": []
+				},
+				"ToNode": {
+					"ID": 1,
+					"Name": "commissions",
+					"Constraints": []
+				}
+			},
+			"Parent": -1,
+			"Children": [
+				1
+			]
+		},
+		{
+			"Self": {
+				"FromNode": {
+					"ID": 2,
+					"Name": "parliament",
+					"Constraints": []
+				},
+				"Rel": {
+					"ID": 1,
+					"Name": "part_of",
+					"FromType": "entity",
+					"FromID": 2,
+					"ToType": "entity",
+					"ToID": 1,
+					"Depth": {
+						"Min": 1,
+						"Max": 1
+					},
+					"Constraints": []
+				},
+				"ToNode": {
+					"ID": 1,
+					"Name": "commissions",
+					"Constraints": []
+				}
+			},
+			"Parent": 0,
+			"Children": [
+				2,
+				3
+			]
+		},
+		{
+			"Self": {
+				"FromNode": {
+					"ID": 2,
+					"Name": "parliament",
+					"Constraints": []
+				},
+				"Rel": {
+					"ID": 2,
+					"Name": "member_of",
+					"FromType": "entity",
+					"FromID": 2,
+					"ToType": "entity",
+					"ToID": 3,
+					"Depth": {
+						"Min": 1,
+						"Max": 1
+					},
+					"Constraints": []
+				},
+				"ToNode": {
+					"ID": 3,
+					"Name": "parties",
+					"Constraints": [
+						{
+							"Attribute": "seats",
+							"Value": "10",
+							"DataType": "int",
+							"MatchType": "LT",
+							"InID": 0,
+							"InType": ""
+						}
+					]
+				}
+			},
+			"Parent": 1,
+			"Children": []
+		},
+		{
+			"Self": {
+				"FromNode": {
+					"ID": 2,
+					"Name": "parliament",
+					"Constraints": []
+				},
+				"Rel": {
+					"ID": 3,
+					"Name": "submits",
+					"FromType": "entity",
+					"FromID": 2,
+					"ToType": "entity",
+					"ToID": 4,
+					"Depth": {
+						"Min": 1,
+						"Max": 1
+					},
+					"Constraints": []
+				},
+				"ToNode": {
+					"ID": 4,
+					"Name": "resolutions",
+					"Constraints": [
+						{
+							"Attribute": "date",
+							"Value": "mei",
+							"DataType": "string",
+							"MatchType": "CONTAINS",
+							"InID": 0,
+							"InType": ""
+						}
+					]
+				}
+			},
+			"Parent": 2,
+			"Children": []
+		}
+	]`)
+	// Clean up the input and expected results
+	cleanedTopNode := strings.ReplaceAll(string(jsonTopNode), "\n", "")
+	cleanedTopNode = strings.ReplaceAll(cleanedTopNode, "\t", "")
+	cleanedTopNode = strings.ReplaceAll(cleanedTopNode, " ", "")
 
-	for i := range JSONQuery.Entities {
-		listoflists := search(&JSONQuery, i)
+	cleanedTreeList := strings.ReplaceAll(string(jsonTreeList), "\n", "")
+	cleanedTreeList = strings.ReplaceAll(cleanedTreeList, "\t", "")
+	cleanedTreeList = strings.ReplaceAll(cleanedTreeList, " ", "")
 
-		fmt.Println(listoflists)
-		sortedListOfLists := make([]entity.PdictList, len(listoflists))
-		for i, list := range listoflists {
-			k := make(entity.PdictList, list.Len())
-			copy(k, list)
-			sort.Sort(k)
-			sortedListOfLists[i] = k
-		}
-		assert.Equal(t, fmt.Sprint(correctResult), fmt.Sprint(sortedListOfLists))
-	}
+	cleanedCorrectTopNode := strings.ReplaceAll(string(correctTopNode), "\n", "")
+	cleanedCorrectTopNode = strings.ReplaceAll(cleanedCorrectTopNode, "\t", "")
+	cleanedCorrectTopNode = strings.ReplaceAll(cleanedCorrectTopNode, " ", "")
+
+	cleanedCorrectTreeList := strings.ReplaceAll(string(correctTreeList), "\n", "")
+	cleanedCorrectTreeList = strings.ReplaceAll(cleanedCorrectTreeList, "\t", "")
+	cleanedCorrectTreeList = strings.ReplaceAll(cleanedCorrectTreeList, " ", "")
 
+	assert.Equal(t, cleanedCorrectTopNode, cleanedTopNode)
+	assert.Equal(t, cleanedCorrectTreeList, cleanedTreeList)
 }
diff --git a/aql/newHierarchy.go b/aql/newHierarchy.go
deleted file mode 100644
index bdd6591..0000000
--- a/aql/newHierarchy.go
+++ /dev/null
@@ -1,113 +0,0 @@
-package aql
-
-import (
-	"git.science.uu.nl/graphpolaris/query-conversion/entity"
-)
-
-// We use consts to define string to prevent typos
-const ENTITYSTRING = "entity"
-const RELATIONSTRING = "relation"
-const GROUPBYSTRING = "groupBy"
-const FILTERSTRING = "filter"
-
-var relationdone map[int]bool
-
-func createHierarchy(JSONQuery *entity.IncomingQueryJSON) ([]entity.Tree, entity.QueryEntityStruct) {
-	var treeList []entity.Tree
-	relationdone = make(map[int]bool)
-	topNode := getTopNode(JSONQuery)
-	topTreeSelfTriple := getTripleFromNode(JSONQuery, topNode)
-	topTree := entity.Tree{
-		Self:     topTreeSelfTriple,
-		Parent:   -1,
-		Children: []int{},
-	}
-	treeList = append(treeList, topTree)
-	treeListIndex := len(treeList) - 1
-	treeList = getChildrenFromTree(JSONQuery, treeList, treeListIndex, 0)
-	return treeList, topNode
-}
-
-/*
-Get a entity that has only 1 relation attached an return its index
-*/
-func getTopNode(JSONQuery *entity.IncomingQueryJSON) entity.QueryEntityStruct {
-	indexOfNodeToReturn := -1
-	for i, node := range JSONQuery.Entities {
-		connectionCount := 0
-		for _, relation := range JSONQuery.Relations {
-			if (relation.FromType == ENTITYSTRING && relation.FromID == node.ID) || (relation.ToType == ENTITYSTRING && relation.ToID == node.ID) {
-				connectionCount++
-			}
-		}
-		if connectionCount == 1 {
-			indexOfNodeToReturn = i
-			return JSONQuery.Entities[indexOfNodeToReturn]
-		}
-	}
-	return JSONQuery.Entities[indexOfNodeToReturn]
-}
-
-func getTripleFromNode(JSONQuery *entity.IncomingQueryJSON, node entity.QueryEntityStruct) entity.Triple {
-	var tripleToReturn entity.Triple
-	for _, relation := range JSONQuery.Relations {
-		// The initial node was our From so we set the Triple accordingly
-		// TODO
-		// If the To is not an entity we might have to do something different
-		if (relation.FromType == ENTITYSTRING && relation.FromID == node.ID) && relation.ToType == ENTITYSTRING {
-			tripleToReturn.FromNode = node
-			tripleToReturn.Rel = relation
-			tripleToReturn.ToNode = JSONQuery.Entities[relation.ToID]
-		} else if (relation.ToType == ENTITYSTRING && relation.ToID == node.ID) && relation.FromType == ENTITYSTRING {
-			tripleToReturn.FromNode = JSONQuery.Entities[relation.ToID]
-			tripleToReturn.Rel = relation
-			tripleToReturn.ToNode = node
-		}
-	}
-	relationdone[tripleToReturn.Rel.ID] = true
-	return tripleToReturn
-}
-
-func getTripleFromRelation(JSONQuery *entity.IncomingQueryJSON, relation entity.QueryRelationStruct) entity.Triple {
-	var tripleToReturn entity.Triple
-	tripleToReturn.FromNode = JSONQuery.Entities[relation.FromID]
-	tripleToReturn.Rel = relation
-	tripleToReturn.ToNode = JSONQuery.Entities[relation.ToID]
-	return tripleToReturn
-}
-
-func getChildrenFromTree(JSONQuery *entity.IncomingQueryJSON, treeList []entity.Tree, treeListIndex int, parentIndex int) []entity.Tree {
-	var childRelationTriples []entity.Triple
-	for i, relation := range JSONQuery.Relations {
-		// We found a relation that is not our parent relation so we can check if it matches on of our nodes
-		// If it matches one of the nodes we can add it
-		if _, ok := relationdone[i]; !ok {
-			if relation.FromType == ENTITYSTRING && relation.FromID == treeList[parentIndex].Self.FromNode.ID {
-				triple := getTripleFromRelation(JSONQuery, relation)
-				childRelationTriples = append(childRelationTriples, triple)
-				relationdone[i] = true
-			} else if relation.ToType == ENTITYSTRING && relation.ToID == treeList[parentIndex].Self.ToNode.ID {
-				triple := getTripleFromRelation(JSONQuery, relation)
-				childRelationTriples = append(childRelationTriples, triple)
-				relationdone[i] = true
-			}
-		}
-	}
-	// We now have all our children, so we can now make those trees and find their children
-	// We can now also add the indices to the list of children from the tree calling this function
-	if len(childRelationTriples) != 0 {
-		for _, triple := range childRelationTriples {
-			childTree := entity.Tree{
-				Self:     triple,
-				Parent:   treeListIndex,
-				Children: []int{},
-			}
-			treeList = append(treeList, childTree)
-			// We get the new treeListIndex, which we can now add to the list of children from the tree calling this function
-			treeListIndex = len(treeList) - 1
-			treeList[parentIndex].Children = append(treeList[parentIndex].Children, treeListIndex)
-			treeList = getChildrenFromTree(JSONQuery, treeList, treeListIndex, treeListIndex)
-		}
-	}
-	return treeList
-}
diff --git a/entity/queryStruct.go b/entity/queryStruct.go
index 248b58c..9cf011e 100644
--- a/entity/queryStruct.go
+++ b/entity/queryStruct.go
@@ -30,14 +30,14 @@ type QueryEntityStruct struct {
 
 // QueryRelationStruct encapsulates a single relation with its corresponding constraints
 type QueryRelationStruct struct {
-	ID                    int
-	Name                  string
-	FromType              string
-	FromID                int
-	ToType                string
-	ToID                  int
-	Depth                 QuerySearchDepthStruct
-	QueryConstraintStruct []QueryConstraintStruct
+	ID          int
+	Name        string
+	FromType    string
+	FromID      int
+	ToType      string
+	ToID        int
+	Depth       QuerySearchDepthStruct
+	Constraints []QueryConstraintStruct
 }
 
 type QueryGroupByStruct struct {
diff --git a/realtest.json b/realtest.json
index 46028cc..30fc8f3 100644
--- a/realtest.json
+++ b/realtest.json
@@ -22,8 +22,8 @@
                 {
                     "attribute": "name",
                     "value": "Geert",
-                    "dataType": "text",
-                    "matchType": "like"
+                    "dataType": "string",
+                    "matchType": "CONTAINS"
                 }
             ]
         },
@@ -44,7 +44,7 @@
                 {
                     "attribute": "seats",
                     "value": "10",
-                    "dataType": "number",
+                    "dataType": "int",
                     "matchType": "LT"
                 }
             ]
@@ -56,8 +56,8 @@
                 {
                     "attribute": "date",
                     "value": "mei",
-                    "dataType": "text",
-                    "matchType": "like"
+                    "dataType": "string",
+                    "matchType": "CONTAINS"
                 }
             ]
         }
-- 
GitLab