iOS
...
Parse Swift SDK
Data Objects

Relational Queries

13min

Relational Queries

Introduction

In the previous guide we detailed how we can perform miscellaneous queries on a Back4App Database. In this guide we focus on a specific type of query that involves objects with relations.

Prerequisites

To complete this tutorial, you will need:

Goal

Query relational data stored on a Back4App Database using the ParseSwift SDK.

1 - Quick review about the Query<U>class

Any query performed on a Back4App Database is done via the generic class Query<U>. The generic parameter U (conforming to the ParseObject protocol) is the data type of the objects we are trying to retrieve from the database.

Given a data type like MyObject, we retrieve these objects from a Back4App Database in the following way

Swift


You can read more about the Query<U> class here at the official documentation.

2 - Save some data on a Back4App Database

Before we begin to execute queries, it is necessary to set up some data on a Back4App Database. We will store five types of objects:

Author
Book
ISBD
Publisher
BookStore


Additionally, in order to construct queries for relational data, we will implement the following relations

  • 1:1 relation between Book and ISBD.
  • 1:N relation between Book and Publisher.
  • M:N relation between Book and Author.
  • M:N relation between BookStore and Book.

We now proceed to store some data on the Back4App Database. This step can be implemented using Swift or directly from your app’s console on the Back4App platform.

Swift
Back4App's console


3 - Query the data

Once the database has some sample data to work with, we start executing the different kinds of queries associated with the relations detailed earlier.

Queries involving 1:1 relations

Given two data types sharing a 1:1 relation (Book and ISBD in this case), we can retrieve one from the other as follows. The way we implemented the relation in Book allows us to retrieve its related ISBD object simply by calling the include(_:) method on the query. Let us retrieve the ISBD from the book A Love Story:

Swift


On the other hand, a query to retrieve a Book object related to a given ISBD is implemented in the following way. By looking at the implementation of ISBD, we note that the relation is represented by the book property (of type Pointer<book>). This pointer provides a set of methods and properties to retrieve information about the object it points to. In particular, we call the fetch(...) method on the book property to fetch the associated Book

Swift


We should remark that this implemetation for a 1:1 relation is not unique. Depending on your use case, you can implement 1:1 relations in different ways.

Queries involving 1:N relations

In a scenario where we need to query all the books published by a given publisher, we first need to retrieve the publisher. For instance, we first retrieve the data object associated with the publisher Acacia Publishings. Depending on the situation, this procces may vary

Swift


Now that we have access to acaciaPublishings, we can construct the query to retrieve its related books. We proceed to create the query by instantiating a Query<Book> class. In this case, this class is instantiated using the static method query(...) provided by the Book object. The (variadic) arguments for this method are the standard QueryConstraint objects. Therefore, the books we are looking for are retrieved with the following snippet

Swift


An asynchronous implentation for the above snippet may be written in the following way

Swift


Queries involving M:N relations (Case 1)

To illustrate this case, we consider the following scenario; we want to list all the stores containing books published after a given date (e.g., 01/01/2010). Firstly we require an intermediate query to select the books. Next, we construct the main query to list the stores.

Therefore, we prepare the first query for the books

Swift


We then construct the stores’ query using booksQuery’s results. The method containedIn(_:array:) returns the constraint we need for this case

Swift


Similarly, we can implement this process asynchronously

Swift


Queries involving M:N relations (Case 2)

Suppose we need to select all the stores that have books written by a given author, say, Aaron Writer. In order to achieve this, we require two additional queries:

  • A query (Query<Author>) to obtain the object associated with the author Aaron Writer.
  • A query (Query<Book>)to select all the books written by Aaron Writer.
  • The main query (Query<BookStore>) to select the stores we are looking for.

The procedure to implement these queries are very similar to the previous ones:

Swift


Conclusion

With the ParseSwift SDK, we were able to construct relational queries that allowed us to select items based on the type of relations they have with other data types.

Updated 20 Mar 2024
Did this page help you?