How to sort in this case?

1 prepare data
alice -starring-> booklist -haveBook-> book.

 {
  set{
    _:bookA  <title> "A smart dog"  .
    _:bookA  <price> "3"  .
     _:bookB  <title>  "Beat the bill"  .
    _:bookB  <price> "4"  .
    _:bookC <title> "Coming soon" .
    _:bookC  <price> "5"  .
    
    _:booklist1 <haveBook> _:bookA .
    _:booklist2 <haveBook> _:bookB .
    _:booklist3 <haveBook> _:bookC  .
    
    _:alice <starring> _:booklist1 .
    _:alice <starring> _:booklist2 .
    _:alice <starring> _:booklist3 .
  }  
}

2 query the data

{
  q(func:has(starring)){
   starring{
   booklist :  haveBook{
      title
      price
    }
  }
  }
}

response:

 "starring": [
          {
            "booklist": [
              {
                "title": "Beat the bill",
                "price": "4"
              }
            ]
          },
          {
            "booklist": [
              {
                "title": "Coming soon",
                "price": "5"
              }
            ]
          },
          {
            "booklist": [
              {
                "title": "A smart dog",
                "price": "3"
              }
            ]
          }
        ]

I want to sort the booklist node via the first book’s price or title in a booklist.

How to write the query?

ref: https://docs.dgraph.io/query-language#sorting

It will not work that way, the best thing to do is call the list first instead of the one that is “starring.”

Alice has three lists, will always return separately, making it impossible to sort.

{
   q (func: has (haveBook)) {
    booklist: haveBook (orderasc: $predicate) {
       title
       price
     }
   }
}

But you could also do expand via Var block. Using groupby. https://docs.dgraph.io/query-language#groupby

@BlankRain You could try something like this:

{
  var(func: has(starring)) {
    starring {  # Gives you booklist.
       haveBook (first: 1, orderdesc: price) {
         p as price # Maps from book -> price. Should only have 1 entry.
       }
       x as sum(p)  # Maps from booklist -> price.
    }
  }

  lists(func: uid(x), orderdesc: val(x)) {
    haveBook { title, price }  # Print the books in the booklist.
  }
}

To see more complex query examples, you can see this:

thank you very much.
I tried your given query.

However, it response

Only variables allowed in aggregate functions. Got: p

It doesn’t work.
:joy::joy::joy:

use this: x as sum(val(p)) # Maps from booklist → price.

Thank you .
It works.

 x as sum(val(p))
{
  var(func: has(starring)) {
    starring {  # Gives you booklist.
       haveBook (first: 1, orderdesc: price) {
         p as title # Maps from book -> price. Should only have 1 entry.
       }
       x as sum(val(p))  # Maps from booklist -> price.
    }
  }

  lists(func: uid(x), orderasc: val(x)) {
    haveBook { title, price }  # Print the books in the booklist.
  }
}

and

{
  var(func: has(starring)) {
    starring {  # Gives you booklist.
       haveBook (first: 1, orderdesc: price) {
         p as price # Maps from book -> price. Should only have 1 entry.
       }
       x as sum(val(p))  # Maps from booklist -> price.
    }
  }

  lists(func: uid(x), orderasc: val(x)) {
    haveBook { title, price }  # Print the books in the booklist.
  }
}

both works.

thank you ,and with the help of @shanghai-Jerry ,now I can sort my booklist via book’s title or price.

Thank you michel.
@mrjn 's answer helps .

1 Like

good

it means than you should not use variable in aggregate function sum, all variable should be used just in uid(…) or val(…)
that’s the most important concept for variable

wish you have good understand about this

by the way, try to read more query examples

:smiley::smiley::smiley:
Thank you.
we should share each other’s expriences in using dgraph.

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