Hi,
I want to implement Conway’s game of life with Dgraph. So far, I created the schema, set initial state and made a query to list cells that should die or born.
Now I want to do an upsert to change my “alive” predicate but I have troubles with the request:
{
"name": "t",
"url": "http://localhost:8080/mutate?commitNow=true",
"errors": [
{
"message": "while lexing uid(tokill) <alive> false . at line 1 column 19: Invalid input: f at lexText",
"extensions": {
"code": "ErrorInvalidRequest"
}
}
]
}
The schema is:
type Cell {
i
j
alive
nextto
}
i: int @index(int) .
j: int @index(int) .
alive: bool @index(bool) .
nextto: [uid] @reverse .
Initial state:
{
"set": [
{
"uid": "_:0_0",
"dgraph.type": "Cell",
"i": 0,
"j": 0,
"alive": false,
"nextto": [
{
"uid": "_:3_1"
},
{
"uid": "_:0_1"
},
{
"uid": "_:1_1"
},
{
"uid": "_:1_0"
}
]
},
{
"uid": "_:0_1",
"dgraph.type": "Cell",
"i": 0,
"j": 1,
"alive": false,
"nextto": [
{
"uid": "_:3_2"
},
{
"uid": "_:0_2"
},
{
"uid": "_:1_2"
},
{
"uid": "_:1_1"
}
]
},
{
"uid": "_:0_2",
"dgraph.type": "Cell",
"i": 0,
"j": 2,
"alive": false,
"nextto": [
{
"uid": "_:3_3"
},
{
"uid": "_:0_3"
},
{
"uid": "_:1_3"
},
{
"uid": "_:1_2"
}
]
},
{
"uid": "_:0_3",
"dgraph.type": "Cell",
"i": 0,
"j": 3,
"alive": false,
"nextto": [
{
"uid": "_:3_0"
},
{
"uid": "_:0_0"
},
{
"uid": "_:1_0"
},
{
"uid": "_:1_3"
}
]
},
{
"uid": "_:1_0",
"dgraph.type": "Cell",
"i": 1,
"j": 0,
"alive": false,
"nextto": [
{
"uid": "_:0_1"
},
{
"uid": "_:1_1"
},
{
"uid": "_:2_1"
},
{
"uid": "_:2_0"
}
]
},
{
"uid": "_:1_1",
"dgraph.type": "Cell",
"i": 1,
"j": 1,
"alive": false,
"nextto": [
{
"uid": "_:0_2"
},
{
"uid": "_:1_2"
},
{
"uid": "_:2_2"
},
{
"uid": "_:2_1"
}
]
},
{
"uid": "_:1_2",
"dgraph.type": "Cell",
"i": 1,
"j": 2,
"alive": false,
"nextto": [
{
"uid": "_:0_3"
},
{
"uid": "_:1_3"
},
{
"uid": "_:2_3"
},
{
"uid": "_:2_2"
}
]
},
{
"uid": "_:1_3",
"dgraph.type": "Cell",
"i": 1,
"j": 3,
"alive": false,
"nextto": [
{
"uid": "_:0_0"
},
{
"uid": "_:1_0"
},
{
"uid": "_:2_0"
},
{
"uid": "_:2_3"
}
]
},
{
"uid": "_:2_0",
"dgraph.type": "Cell",
"i": 2,
"j": 0,
"alive": false,
"nextto": [
{
"uid": "_:1_1"
},
{
"uid": "_:2_1"
},
{
"uid": "_:3_1"
},
{
"uid": "_:3_0"
}
]
},
{
"uid": "_:2_1",
"dgraph.type": "Cell",
"i": 2,
"j": 1,
"alive": true,
"nextto": [
{
"uid": "_:1_2"
},
{
"uid": "_:2_2"
},
{
"uid": "_:3_2"
},
{
"uid": "_:3_1"
}
]
},
{
"uid": "_:2_2",
"dgraph.type": "Cell",
"i": 2,
"j": 2,
"alive": true,
"nextto": [
{
"uid": "_:1_3"
},
{
"uid": "_:2_3"
},
{
"uid": "_:3_3"
},
{
"uid": "_:3_2"
}
]
},
{
"uid": "_:2_3",
"dgraph.type": "Cell",
"i": 2,
"j": 3,
"alive": true,
"nextto": [
{
"uid": "_:1_0"
},
{
"uid": "_:2_0"
},
{
"uid": "_:3_0"
},
{
"uid": "_:3_3"
}
]
},
{
"uid": "_:3_0",
"dgraph.type": "Cell",
"i": 3,
"j": 0,
"alive": false,
"nextto": [
{
"uid": "_:2_1"
},
{
"uid": "_:3_1"
},
{
"uid": "_:0_1"
},
{
"uid": "_:0_0"
}
]
},
{
"uid": "_:3_1",
"dgraph.type": "Cell",
"i": 3,
"j": 1,
"alive": false,
"nextto": [
{
"uid": "_:2_2"
},
{
"uid": "_:3_2"
},
{
"uid": "_:0_2"
},
{
"uid": "_:0_1"
}
]
},
{
"uid": "_:3_2",
"dgraph.type": "Cell",
"i": 3,
"j": 2,
"alive": false,
"nextto": [
{
"uid": "_:2_3"
},
{
"uid": "_:3_3"
},
{
"uid": "_:0_3"
},
{
"uid": "_:0_2"
}
]
},
{
"uid": "_:3_3",
"dgraph.type": "Cell",
"i": 3,
"j": 3,
"alive": false,
"nextto": [
{
"uid": "_:2_0"
},
{
"uid": "_:3_0"
},
{
"uid": "_:0_0"
},
{
"uid": "_:0_3"
}
]
}
]
}
The following query returns the good result (by the way, is there a better way to count edges?):
{
living as var(func: eq(alive, true)) {
num_alive_nextto_living as count(nextto) @filter (eq(alive, true))
num_alive_nextto_living_r as count(~nextto) @filter (eq(alive, true))
num_alive_neibours as math(num_alive_nextto_living + num_alive_nextto_living_r)
}
tokill(func: uid(living)) @filter(lt(val(num_alive_neibours), 2) or gt(val(num_alive_neibours), 3)){
i
j
}
dead as var(func: eq(alive, false)){
num_alive_nextto_dead as count(nextto) @filter (eq(alive, true))
num_alive_nextto_dead_r as count(~nextto) @filter (eq(alive, true))
num_death_neibours as math(num_alive_nextto_dead + num_alive_nextto_dead_r)
}
toborn(func: uid(dead)) @filter(eq(val(num_death_neibours), 3)){
i
j
}
}
Result:
{
"data": {
"tokill": [
{
"i": 2,
"j": 1
},
{
"i": 2,
"j": 3
}
],
"toborn": [
{
"i": 1,
"j": 2
},
{
"i": 3,
"j": 2
}
]
},
"extensions": {
"server_latency": {
"parsing_ns": 306809,
"processing_ns": 2751609,
"encoding_ns": 67252,
"total_ns": 3270064
},
"txn": {
"start_ts": 3846
},
"metrics": {
"num_uids": {
"": 3,
"_total": 114,
"alive": 52,
"i": 4,
"j": 4,
"nextto": 16,
"num_alive_neibours": 6,
"num_death_neibours": 13,
"~nextto": 16
}
}
}
}
But
This mutation fails:
upsert{
query {
{
living as var(func: eq(alive, true)) {
num_alive_nextto_living as count(nextto) @filter (eq(alive, true))
num_alive_nextto_living_r as count(~nextto) @filter (eq(alive, true))
num_alive_neibours as math(num_alive_nextto_living + num_alive_nextto_living_r)
}
tokill as var(func: uid(living)) @filter(lt(val(num_alive_neibours), 2) or gt(val(num_alive_neibours), 3)){
i
j
}
dead as var(func: eq(alive, false)){
num_alive_nextto_dead as count(nextto) @filter (eq(alive, true))
num_alive_nextto_dead_r as count(~nextto) @filter (eq(alive, true))
num_death_neibours as math(num_alive_nextto_dead + num_alive_nextto_dead_r)
}
toborn as var(func: uid(dead)) @filter(eq(val(num_death_neibours), 3)){
i
j
}
}
}
mutation {
set {
uid(tokill) <alive> false .
uid(toborn) <alive> true .
}
}
}
As well as this one:
upsert{
query {
{
living as var(func: eq(alive, true)) {
num_alive_nextto_living as count(nextto) @filter (eq(alive, true))
num_alive_nextto_living_r as count(~nextto) @filter (eq(alive, true))
num_alive_neibours as math(num_alive_nextto_living + num_alive_nextto_living_r)
}
var(func: uid(living)) @filter(lt(val(num_alive_neibours), 2) or gt(val(num_alive_neibours), 3)){
tokill as uid
}
dead as var(func: eq(alive, false)){
num_alive_nextto_dead as count(nextto) @filter (eq(alive, true))
num_alive_nextto_dead_r as count(~nextto) @filter (eq(alive, true))
num_death_neibours as math(num_alive_nextto_dead + num_alive_nextto_dead_r)
}
var(func: uid(dead)) @filter(eq(val(num_death_neibours), 3)){
toborn as uid
}
}
}
mutation {
set {
uid(tokill) <alive> false .
uid(toborn) <alive> true .
}
}
}
With this error:
{
"name": "t",
"url": "http://localhost:8080/mutate?commitNow=true",
"errors": [
{
"message": "while lexing uid(tokill) <alive> false . at line 1 column 19: Invalid input: f at lexText",
"extensions": {
"code": "ErrorInvalidRequest"
}
}
]
}
What do I miss ?
Edit: I tried to quote values like this:
uid(tokill) <alive> "false" .
uid(toborn) <alive> "true" .
and like this:
uid(tokill) <alive> "false"<xs:boolean> .
uid(toborn) <alive> "true"<xs:boolean> .
Without more success:
{
"name": "t",
"url": "http://localhost:8080/mutate?commitNow=true",
"errors": [
{
"message": "line 2 column 8: Expected some name. Got: lex.Item [6] \"{\" at 2:8",
"extensions": {
"code": "ErrorInvalidRequest"
}
}
]
}