Order by a generated variable

Hello! Imagine I have this query:

query { 
    bills(func: has(billsType)) @filter(has(billsType))
    {
        uid
        date
        billItems @filter(has(billItemsType))
        {
            uid
            name
            amount_var AS amount
        }
        total: sum(val(amount_var))
    }
}

How do I go about sorting the result by the value of total? If I simply add orderasc like so:

query { 
    bills(func: has(billsType), orderasc: val(total_val) @filter(has(billsType))
    {
        uid
        date
        billItems @filter(has(billItemsType))
        {
            uid
            name
            amount_var AS amount
        }
        total_val as total: sum(val(amount_var))
    }
}

I get the error:

Variable: [total_var] used before definition.

I figured I should run the first query as a variable, and then run an orderasc on something which references it, but for example if I do this:

query { 
    firstSearch AS bills(func: has(billsType)) @filter(has(billsType))
    {
        uid
        date
        billItems @filter(has(billItemsType))
        {
            uid
            name
            amount_var AS amount
        }
        total: sum(val(amount_var))
    }
          
    results(func: uid(firstSearch)) {
      expand(_all_)
    }
}

The “results” query does not include the total that was calculated earlier.

Clearly I’m missing something basic (as usual), so my question is simply how can I sort a query by a variable generated within the query itself?

1 Like

You can use multiple query blocks to accomplish this. For example, take a look at the example queries in the docs: https://docs.dgraph.io/query-language/#math-on-value-variables

1 Like

Hi Michael Beeson,

First: You can not use a variable created in Query itself for The Query itself. You need to create a Query sequence as “pipe” in order to do sorting. Gives the error “used before definition”.

Second: Avoid using more than one “has” with the same predicate. You are using “has (billsType)” and “@filter (has (billsType))” - This has no effect whatsoever, it can delay in ms.

Third: See this query “Aggregation* Usage at other levels” at https://docs.dgraph.io/query-language/#aggregation - In it we have an usage similar to yours. It uses aggregation, variable propagation and sorting by variable.

If it still does not help, please provide a small mutation example according to its structure so that I can replicate here and offer you a better wayout. Can be in JSON tho.

Cheers.

1 Like

Hi there Michel!

The double use of “has” is due to an apparent bug where the uids of nodes that used to have the predicate, but have had that edge deleted, still turn up when doing a simple func: has(billType). I know the solution is hacky, but it works, and in fact it was suggested to me by you yourself right here:

As for the problem itself, I’m playing around with the best solution, my issue being finding a decent way to abstract it out enough to generate queries that can sort by such variables. Thanks to both of you for the links!

1 Like

hahahha yeah I remember that now. (Will stop when we change the posting sys)

Well, feel free to ping us.

Cheers.

1 Like

Heya! I’ve just upgraded dgraph and can confirm the phantom uids are no longer showing up. Thanks! I’ll be removing that superfluous filter from my searches now

2 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.