Ok. Iām 95% sure this is a bug, and I guess I should open an issue with the Core Dev, but I still consider myself a dgraph noob and I want to convince you first, Michel, because youāve been so helpful all along.
Maybe this makes more sense with real data that makes sense, so how about this? We have users where their first name and last name are stored separately. Imagine we have two users, one called āMichel Beesonā and one called āMichel Conradā. Now in dgraph, if we were to order only by first name, thereās no guarantee that Michel Beeson should appear before Michel Conrad. We would have to say āfirst, order by first name, and if the first name is the same, then order by last nameā. So hereās a mutation that creates a bunch of users, who are either called āMichelā or āSusanā, but they have different surnames.
I will also add a predicate called ānaturalOrderā which corresponds to the order that you would expect (ascending).
{
"set": [
{
"firstName": "Michel",
"lastName": "Antwerp",
"naturalOrder": 1
},
{
"firstName": "Michel",
"lastName": "Beeson",
"naturalOrder": 2
},
{
"firstName": "Michel",
"lastName": "Conrad",
"naturalOrder": 3
},
{
"firstName": "Michel",
"lastName": "Fittspatrick",
"naturalOrder": 4
},
{
"firstName": "Michel",
"lastName": "Wallace",
"naturalOrder": 5
},
{
"firstName": "Michel",
"lastName": "Zabala",
"naturalOrder": 6
},
{
"firstName": "Susan",
"lastName": "Button",
"naturalOrder": 7
},
{
"firstName": "Susan",
"lastName": "Dillan",
"naturalOrder": 8
},
{
"firstName": "Susan",
"lastName": "Grande",
"naturalOrder": 9
},
{
"firstName": "Susan",
"lastName": "Jackson",
"naturalOrder": 10
},
{
"firstName": "Susan",
"lastName": "Lawrence",
"naturalOrder": 11
},
{
"firstName": "Susan",
"lastName": "Palmer",
"naturalOrder": 12
},
{
"firstName": "Susan",
"lastName": "Ralley",
"naturalOrder": 13
},
{
"firstName": "Susan",
"lastName": "Trenton",
"naturalOrder": 14
}
]
}
Now Iām going to do some simple queries without pagination, just to be extra annoying and exhaustive. If I just do:
query {
users(func: has(firstName)) {
expand(_all_)
}
}
I get:
"data": {
"users": [
{
"lastName": "Beeson",
"naturalOrder": 2,
"firstName": "Michel"
},
{
"lastName": "Wallace",
"naturalOrder": 5,
"firstName": "Michel"
},
{
"lastName": "Button",
"naturalOrder": 7,
"firstName": "Susan"
},
{
"lastName": "Dillan",
"naturalOrder": 8,
"firstName": "Susan"
},
{
"lastName": "Conrad",
"naturalOrder": 3,
"firstName": "Michel"
},
{
"lastName": "Jackson",
"naturalOrder": 10,
"firstName": "Susan"
},
{
"lastName": "Trenton",
"naturalOrder": 14,
"firstName": "Susan"
},
{
"lastName": "Zabala",
"naturalOrder": 6,
"firstName": "Michel"
},
{
"lastName": "Grande",
"naturalOrder": 9,
"firstName": "Susan"
},
{
"lastName": "Lawrence",
"naturalOrder": 11,
"firstName": "Susan"
},
{
"lastName": "Antwerp",
"naturalOrder": 1,
"firstName": "Michel"
},
{
"lastName": "Fittspatrick",
"naturalOrder": 4,
"firstName": "Michel"
},
{
"lastName": "Palmer",
"naturalOrder": 12,
"firstName": "Susan"
},
{
"lastName": "Ralley",
"naturalOrder": 13,
"firstName": "Susan"
}
]
}
Totally random and as it should be. So lets sort by firstName descending:
query {
users(func: has(firstName), orderdesc: firstName) {
expand(_all_)
}
}
The results are:
"data": {
"users": [
{
"lastName": "Grande",
"naturalOrder": 9,
"firstName": "Susan",
"uid": "0x2724"
},
{
"lastName": "Palmer",
"naturalOrder": 12,
"firstName": "Susan",
"uid": "0x2728"
},
{
"lastName": "Button",
"naturalOrder": 7,
"firstName": "Susan",
"uid": "0x271e"
},
{
"lastName": "Dillan",
"naturalOrder": 8,
"firstName": "Susan",
"uid": "0x271f"
},
{
"lastName": "Lawrence",
"naturalOrder": 11,
"firstName": "Susan",
"uid": "0x2725"
},
{
"lastName": "Jackson",
"naturalOrder": 10,
"firstName": "Susan",
"uid": "0x2721"
},
{
"lastName": "Trenton",
"naturalOrder": 14,
"firstName": "Susan",
"uid": "0x2722"
},
{
"lastName": "Ralley",
"naturalOrder": 13,
"firstName": "Susan",
"uid": "0x2729"
},
{
"lastName": "Zabala",
"naturalOrder": 6,
"firstName": "Michel",
"uid": "0x2723"
},
{
"lastName": "Conrad",
"naturalOrder": 3,
"firstName": "Michel",
"uid": "0x2720"
},
{
"lastName": "Antwerp",
"naturalOrder": 1,
"firstName": "Michel",
"uid": "0x2726"
},
{
"lastName": "Fittspatrick",
"naturalOrder": 4,
"firstName": "Michel",
"uid": "0x2727"
},
{
"lastName": "Wallace",
"naturalOrder": 5,
"firstName": "Michel",
"uid": "0x271d"
},
{
"lastName": "Beeson",
"naturalOrder": 2,
"firstName": "Michel",
"uid": "0x271c"
}
]
}
Well we get the āSusansā before the āMichelsā, but when it comes to their last names, the order is random. Thatās not what we want. When the first names are the same, we want to sort by last name, so we use the following query:
query {
users(func: has(firstName), orderdesc: firstName, orderdesc: lastName) {
expand(_all_)
}
}
And we get the result:
"data": {
"users": [
{
"naturalOrder": 14,
"firstName": "Susan",
"lastName": "Trenton"
},
{
"naturalOrder": 13,
"firstName": "Susan",
"lastName": "Ralley"
},
{
"naturalOrder": 12,
"firstName": "Susan",
"lastName": "Palmer"
},
{
"naturalOrder": 11,
"firstName": "Susan",
"lastName": "Lawrence"
},
{
"naturalOrder": 10,
"firstName": "Susan",
"lastName": "Jackson"
},
{
"naturalOrder": 9,
"firstName": "Susan",
"lastName": "Grande"
},
{
"naturalOrder": 8,
"firstName": "Susan",
"lastName": "Dillan"
},
{
"naturalOrder": 7,
"firstName": "Susan",
"lastName": "Button"
},
{
"naturalOrder": 6,
"firstName": "Michel",
"lastName": "Zabala"
},
{
"naturalOrder": 5,
"firstName": "Michel",
"lastName": "Wallace"
},
{
"naturalOrder": 4,
"firstName": "Michel",
"lastName": "Fittspatrick"
},
{
"naturalOrder": 3,
"firstName": "Michel",
"lastName": "Conrad"
},
{
"naturalOrder": 2,
"firstName": "Michel",
"lastName": "Beeson"
},
{
"naturalOrder": 1,
"firstName": "Michel",
"lastName": "Antwerp"
}
]
}
Aha! Perfect ordering! This is exactly what I want. I want to emphasize that the ordering is not confused. Dgraph has it exactly right. The bug that Iām talking about is only an issue when it comes to pagination. So letās try some pagination now. I wonāt bother with āoffset: 0ā because then there is no problem. Letās try this:
query {
users(func: has(firstName), orderdesc: firstName, orderdesc: lastName, offset: 3, first: 8) {
expand(_all_)
}
}
The results are:
"data": {
"users": [
{
"lastName": "Trenton",
"naturalOrder": 14,
"firstName": "Susan"
},
{
"lastName": "Ralley",
"naturalOrder": 13,
"firstName": "Susan"
},
{
"lastName": "Lawrence",
"naturalOrder": 11,
"firstName": "Susan"
},
{
"lastName": "Jackson",
"naturalOrder": 10,
"firstName": "Susan"
},
{
"lastName": "Dillan",
"naturalOrder": 8,
"firstName": "Susan"
},
{
"lastName": "Zabala",
"naturalOrder": 6,
"firstName": "Michel"
},
{
"lastName": "Wallace",
"naturalOrder": 5,
"firstName": "Michel"
},
{
"lastName": "Fittspatrick",
"naturalOrder": 4,
"firstName": "Michel"
}
]
}
What happened?! Exactly what I pointed out in earlier posts. Offset is discarding the first 3 results of āorderdesc: firstNameā and ignoring the second order command. This is not an ordering issue; when I perform the query without pagination the order is correct. The problem is with offset.
Please try this with the dataset I have provided. Youāll see that the issue is real. Tomorrow Iāll happily open this as an issue with the Core Dev, just as soon as I figure out how to do that. But Michel, youāve been a real super hero for me, so I feel itās only right that I get you on my side.