# Filter and sort query results · Your first Rell app on Chromia · Learn Chromia

> This part of the tutorial shows you how to write structured queries in Rell that filter and sort data, so users get the results they need. Rell's relational…

Source: https://chromia.com/learn/book-review/sign-transaction/structure/

Your first Rell app on ChromiaLesson 17 of 26

1. [01Your first Rell app on Chromia](https://chromia.com/learn/book-review/introduction/)
2. [02Set up your project](https://chromia.com/learn/book-review/setup/)
3. [03Rell project structure](https://chromia.com/learn/book-review/rell-structure/)

Part 1: Define your first entity

1. [04Overview](https://chromia.com/learn/book-review/book-entity/)
2. [05Create your first entity](https://chromia.com/learn/book-review/book-entity/tables/)
3. [06Add your first operation](https://chromia.com/learn/book-review/book-entity/basic-operations/)
4. [07Query every book](https://chromia.com/learn/book-review/book-entity/write-queries/)

Part 2: Add a related entity

1. [08Overview](https://chromia.com/learn/book-review/book-review-entity/)
2. [09Define the book review entity](https://chromia.com/learn/book-review/book-review-entity/tables/)
3. [10Add an operation for creating book reviews](https://chromia.com/learn/book-review/book-review-entity/basic-operations/)
4. [11Query all reviews for a book](https://chromia.com/learn/book-review/book-review-entity/write-queries/)

Part 3: Checking and validating inputs

1. [12Overview](https://chromia.com/learn/book-review/input-verification/)
2. [13Verify inputs](https://chromia.com/learn/book-review/input-verification/input-verification/)
3. [14Return structured results from queries](https://chromia.com/learn/book-review/input-verification/structure/)

Part 4: Signing transactions and filtering queries

1. [15Overview](https://chromia.com/learn/book-review/sign-transaction/)
2. [16Sign a transaction](https://chromia.com/learn/book-review/sign-transaction/sign-transaction/)
3. [17Filter and sort query results](https://chromia.com/learn/book-review/sign-transaction/structure/)

Part 5: Blockchain state and transactions explained

1. [18Overview](https://chromia.com/learn/book-review/blockchain-transactions/)
2. [19How blockchain state and transactions work](https://chromia.com/learn/book-review/blockchain-transactions/query-transaction/)
3. [20Walking through an example](https://chromia.com/learn/book-review/blockchain-transactions/example/)

Part 6: Create the client

1. [21Overview](https://chromia.com/learn/book-review/build-client/)
2. [22Prerequisites](https://chromia.com/learn/book-review/build-client/prerequisites/)
3. [23Establishing a connection to Chromia](https://chromia.com/learn/book-review/build-client/sign-transaction/)
4. [24Query the blockchain using postchain-client](https://chromia.com/learn/book-review/build-client/query-blockchain/)
5. [25Complete the example](https://chromia.com/learn/book-review/build-client/complete-example/)

1. [26What’s next?](https://chromia.com/learn/book-review/what-next/)

[Learn](https://chromia.com/learn/)[Your first Rell app on Chromia](https://chromia.com/learn/book-review/)

17 / 26Part 4: Signing transactions and filtering queriesBeginner

# Filter and sort query results

This part of the tutorial shows you how to write structured queries in Rell that filter and sort data, so users get the results they need. Rell's relational expressions all share one consistent shape, which keeps data retrieval predictable.

Every structured query in Rell is built from five parts:

1. **FROM**: the data source. You can join and filter it.
2. **CARDINALITY**: how many results are expected, set with an operator such as @, @\*, @+, or @?.
3. **WHERE**: the conditions and joins that filter the data.
4. **WHAT**: the projection, aggregation, and sort order.
5. **LIMIT**: the maximum number of elements returned.

Rell evaluates a query logically in this order, so the execution sequence is always clear.

## Filtering reviews by rating

Start with a new query, `get_reviews_by_rating`, that returns only the reviews with a given rating. The full query is below, followed by a breakdown:

src/main/queries.rell

```
query get_reviews_by_rating(rating: integer) {
  return book_review @* { .rating == rating } (
    .book.to_struct(),
    .reviewer_name,
    .review,
    .rating
  );
}
```

The parts of this query map as follows:

* **FROM**: `book_review`
* **CARDINALITY**: `@*`
* **WHERE**: `{ .rating == rating }`
* **WHAT**: `( .book.to_struct(), .reviewer_name, .review, .rating )`  
  (Calling `.book.to_struct()` reads a referenced entity, which causes an implicit join.)

## Testing filtered reviews

To confirm the query returns only reviews with the requested rating, write a test for it in your test module.

### Updating imports

Add the new query to the imports in your test file:

src/test/book\_review\_test.rell

```nolines
import main.{ book, create_book, get_all_books, book_review, create_book_review, get_reviews_by_rating };
```

### Adding a test function

Then add this test function to check the query's behavior:

src/test/book\_review\_test.rell

```
function test_get_reviews_by_rating() {
    rell.test.tx()
        .op(create_book("123", "Book1", "Author1"))
        .op(create_book_review("123", "Reviewer1", "ReviewText1", 4))
        .op(create_book_review("123", "Reviewer2", "ReviewText2", 5))
        .op(create_book_review("123", "Reviewer3", "ReviewText3", 4))
        .op(create_book_review("123", "Reviewer4", "ReviewText4", 1))
        .sign(book_keeper)
        .run();
    val reviews = get_reviews_by_rating(4);
    assert_equals(reviews.size(), 2);
}
```

The test creates a book, posts four reviews with varying ratings, queries for reviews rated 4, and asserts that exactly two come back.

## Sorting reviews by rating

Next, add sorting. You'll modify the existing `get_all_reviews_for_book` query so it orders reviews by rating. The version below sorts in ascending order; for descending order, use `@sort_desc` instead:

src/main/queries.rell

```
query get_all_reviews_for_book(isbn: text) {
  require(book @? { .isbn == isbn }, "Book with ISBN %s not found".format(isbn));
  val reviews = book_review @* { .book.isbn == isbn } (
    @omit @sort_desc .rating, // Sort by rating, but omit this field in the result.
    book_review_dto(
      book = .book.to_struct(),
      .reviewer_name,
      .review,
      .rating
    )
  );
  return reviews;
}
```

### Updating imports

Include this query in your test file's imports:

src/test/book\_review\_test.rell

```nolines
import main.{ book, create_book, get_all_books, book_review, create_book_review, get_reviews_by_rating, get_all_reviews_for_book };
```

### Adding a test function

Add this test function to confirm the sort order:

src/test/book\_review\_test.rell

```
function test_get_sorted_reviews_by_rating() {
    rell.test.tx()
        .op(create_book("123", "Book1", "Author1"))
        .op(create_book_review("123", "Reviewer1", "ReviewText1", 5))
        .op(create_book_review("123", "Reviewer2", "ReviewText2", 2))
        .op(create_book_review("123", "Reviewer3", "ReviewText3", 4))
        .sign(book_keeper)
        .run();
    val reviews = get_all_reviews_for_book("123");
    assert_equals(reviews.size(), 3);
    assert_equals(reviews[0].rating, 5);
    assert_equals(reviews[1].rating, 4);
    assert_equals(reviews[2].rating, 2);
}
```

The test creates a book, posts three reviews with different ratings, queries for the reviews in ascending rating order, and asserts that they arrive in the correct sequence.

## Running the tests

Run this command to execute the tests and check your queries:

sh

```nolines
chr test
```

Your application now supports filtering and sorting: an administrator can add books, any user can post reviews of them, and you can query books and reviews with filtered, sorted results.

Written for this site from Chromia’s public course. Code samples are the course’s own.

[← Previous**Sign a transaction**](https://chromia.com/learn/book-review/sign-transaction/sign-transaction/)[Next →**Part 5: Blockchain state and transactions explained**](https://chromia.com/learn/book-review/blockchain-transactions/)

On this page

* [Filtering reviews by rating](#filtering-reviews-by-rating)
* [Testing Filtered Reviews](#testing-filtered-reviews)
* [Sorting reviews by rating](#sorting-reviews-by-rating)
* [Running the tests](#running-the-tests)
