diff --git a/cypher/clustering.go b/cypher/clustering.go index 433b77e5fc4124a46b06c4e068436f4a4b4b6c3e..fce64528c4c5d2e1b489d7bdccd4cec4ca2f2a0b 100644 --- a/cypher/clustering.go +++ b/cypher/clustering.go @@ -97,6 +97,11 @@ func checkForQueryCluster(JSONQuery *entity.IncomingQueryJSON) (*entity.Incoming self := fmt.Sprintf("e%v", ent.ID) for _, con := range ent.Constraints { + if con.InType == "" { + con.InID = -1 + continue + } + if con.InID != -1 { in := fmt.Sprintf("%v%v", string(con.InType[0]), con.InID) diff --git a/cypher/convertQuery.go b/cypher/convertQuery.go index 69877f2b260c295cae54b95139eabe1273542274..aa4af78e686fcc75403db2783f5edb61da127d3e 100644 --- a/cypher/convertQuery.go +++ b/cypher/convertQuery.go @@ -128,7 +128,7 @@ func createReturnStatement(JSONQuery *entity.IncomingQueryJSON, parts entity.Que } idstr += "L" } - returnlist = append(returnlist, fmt.Sprintf("eg%v", idstr)) // HIER GAAT NOG WAT MIS (TODO) + returnlist = append(returnlist, fmt.Sprintf("eg%v", idstr)) } } @@ -146,7 +146,7 @@ func createReturnStatement(JSONQuery *entity.IncomingQueryJSON, parts entity.Que } idstr += "L" } - returnlist = append(returnlist, fmt.Sprintf("eg%v", idstr)) // Hier vgm ook, ffkes kijken hoe en wat het zit met relaties aan een groupby + returnlist = append(returnlist, fmt.Sprintf("eg%v", idstr)) } } } else if part.QType == "entity" { @@ -577,17 +577,3 @@ func createGroupByCypher(JSONQuery *entity.IncomingQueryJSON, part entity.QueryP retString := unwindBy + unwindGroup + with + gConstraints return &retString, nil } - -// // Manier voor groupby's op samengevoegde entities -// CALL { -// MATCH p0 = (e11:Person)-[:DIRECTED*1..1]-(e12:Movie) -// UNWIND relationships(p0) as r10 -// Return e11 as e1, e12 as e2 -// UNION -// MATCH p1 = (e13:Person)-[:ACTED_IN]-(e14:Movie) -// UNWIND relationships(p1) as r11 -// Return e13 as e1, e14 as e2 -// } -// WITH e1.bornIn AS e1_bornIn, AVG(e2.budget) AS AVG_budget -// RETURN e1_bornIn, AVG_budget -// LIMIT 5000 diff --git a/cypher/convertQuery_test.go b/cypher/convertQuery_test.go index 39e03039590cfb08b6f479cc47d1154a3108320c..ce72e41065c0ba2bf05b429216def2820775dd1b 100644 --- a/cypher/convertQuery_test.go +++ b/cypher/convertQuery_test.go @@ -132,6 +132,113 @@ func TestGroupBy(t *testing.T) { fmt.Println(*cypher) assert.Equal(t, trimmedAnswer, trimmedCypher) +} +func TestNoInID(t *testing.T) { + query := []byte(`{ + "return": { + "entities": [ + 12, + 13, + 17 + ], + "relations": [ + 11, + 16 + ], + "groupBys": [] + }, + "entities": [ + { + "name": "Order", + "ID": 12, + "constraints": [] + }, + { + "name": "Product", + "ID": 13, + "constraints": [] + }, + { + "name": "Supplier", + "ID": 17, + "constraints": [ + { + "attribute": "country", + "value": "Netherlands", + "dataType": "string", + "matchType": "exact" + } + ] + } + ], + "relations": [ + { + "ID": 11, + "name": "ORDERS", + "depth": { + "min": 1, + "max": 1 + }, + "fromType": "entity", + "fromID": 12, + "toType": "entity", + "toID": 13, + "constraints": [] + }, + { + "ID": 16, + "name": "SUPPLIES", + "depth": { + "min": 1, + "max": 1 + }, + "fromType": "entity", + "fromID": 17, + "toType": "entity", + "toID": 13, + "constraints": [] + } + ], + "groupBys": [], + "machineLearning": [], + "limit": 5000, + "databaseName": "Northwind" + } + `) + + var JSONQuery entity.IncomingQueryJSON + json.Unmarshal(query, &JSONQuery) + + s := NewService() + cypher, err := s.ConvertQuery(&JSONQuery) + if err != nil { + fmt.Println(err) + return + } + + answer := `MATCH p0 = (e0:parliament)-[:member_of*1..1]-(e1:parties) + WHERE e0.name CONTAINS "%Geert%" +UNWIND relationships(p0) as r0 +WITH * +MATCH p1 = (e0:parliament)-[:submits*1..1]-(e2:resolutions) + WHERE e0.name CONTAINS "%Geert%" +UNWIND relationships(p1) as r1 +WITH * +UNWIND [r1,e0,e2,r0,e0,e1] AS x +RETURN DISTINCT x +LIMIT 5000;nodelink` + + fmt.Println(*cypher) + + trimmedCypher := strings.Replace(*cypher, "\n", "", -1) + trimmedCypher = strings.Replace(trimmedCypher, "\t", "", -1) + + trimmedAnswer := strings.Replace(answer, "\n", "", -1) + trimmedAnswer = strings.Replace(trimmedAnswer, "\t", "", -1) + + fmt.Println(*cypher) + assert.Equal(t, trimmedAnswer, trimmedCypher) + } func TestSmallChain(t *testing.T) { query := []byte(`{ diff --git a/entity/queryStruct.go b/entity/queryStruct.go index a2232f9766de0a0166aa6e0e2d226005abb5b0f0..7047e01ef098e7aa4f4654613e4f94fe90b81247 100644 --- a/entity/queryStruct.go +++ b/entity/queryStruct.go @@ -120,11 +120,10 @@ func (JSONQuery IncomingQueryJSON) FindG(qID int) *QueryGroupByStruct { // QueryPart is a struct containing a part of the query and a list of dependencies on which this part of the query depends type QueryPart struct { - QType string // Eg if it is a relation or groupby - QID int // ID of said relation/gb - PartID int // Custom ID used for dependency - Dependencies []int // List of partID's that need to come before - NestedPart *QueryPart // Pointer to another part, used in some cases to avoid cycles + QType string // Eg if it is a relation or groupby + QID int // ID of said relation/gb + PartID int // Custom ID used for dependency + Dependencies []int // List of partID's that need to come before } // Query is a list of (possibly unordered) queryparts