This one, a “chain of edges” is good. You can reduce it to a single edge. Instead of two. And use the reverse index.
That’s a good point. Without an index, Dgraph can’t guarantee order.
But if you use a single edge with a 1 to 1 relation. This ordering can be overcome manually.
Some points about Chain of Edges
Use this filter below to find the first entity in the chain
articles @filter(not has(<~next>)) {
And below to find the last
articles @filter(not has(<next>)) {
These filters can be useful to do a kind of “POP/SHIFT” Method (just like JavaScript) in combination with Upsert Block.
e.g:
This will remove the first element in the chain of nodes. And promote the second in the line as the first node.
upsert {
query {
v as var(func: eq(title, "Series ABC" ) ){
G as articles @filter(not has(<~next>)) {
shiftTo as next
}
}
}
mutation {
delete {
uid(v) <articles> uid(G) .
uid(G) <next> uid(shiftTo) . #we need this to avoid collision
#You can also do " uid(G) * * . " to delete the whole node instead of just relations.
}
}
}
This will “pop” the last node in the chain.
upsert {
query {
v as var(func: eq(title, "Series ABC" ) ){
G as articles @filter(not has(<next>)) {
pop as <~next>
}
}
}
mutation {
delete {
uid(v) <articles> uid(G) .
uid(pop) <next> * .
}
}
}
Note that in with these queries above we are only deleting the relationships. If you also want to delete the node being removed from the chain. You can add something like Delete "S * * " :
delete { uid(G) * * . }
With Chain of Edges you don’t need pagination.
As you have the UID of the article you are in. You can query the next and the previous UID like the query below. And you can go even further, just add more edges to traverse and aliases to them.
{
query(func: eq(title, "Series ABC" )) @normalize{
articles @filter(uid(0x9c85)) {
<~next> {
previous : title
previousuid: uid
}
next {
next: title
nextuid: uid
}
}
}
}
Result
{
"data": {
"query": [
{
"next": "fourth article",
"nextuid": "0x9c84",
"previous": "second article",
"previousuid": "0x9c86"
}
]
}
}
Queries
{
var(func: eq(title, "Series ABC" )){
G as articles @filter(not has(<~next>))
}
q(func: uid(G)) @recurse {
uid : uid
title : title
next @normalize
}
}
response:
{
"data": {
"q": [
{
"uid": "0x9c5d",
"title": "first article",
"next": [
{
"title": [
"second article",
"third article",
"fourth article",
"fifth article",
"sixth article"
],
"uid": "0x9c58"
}
]
}
]
}
}
Sample dataset
{
"set": [
{
"title": "Series ABC",
"articles": [
{
"uid": "_:article06",
"title": "sixth article",
"body": ""
},
{
"uid": "_:article05",
"title": "fifth article",
"body": "",
"next": {
"uid": "_:article06"
}
},
{
"uid": "_:article04",
"title": "fourth article",
"body": "",
"next": {
"uid": "_:article05"
}
},
{
"uid": "_:article03",
"title": "third article",
"body": "",
"next": {
"uid": "_:article04"
}
},
{
"uid": "_:article02",
"title": "second article",
"body": "",
"next": {
"uid": "_:article03"
}
},
{
"uid": "_:article01",
"title": "first article",
"body": "",
"next": {
"uid": "_:article02"
}
}
]
}
]
}