Performing Efficient Queries

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

In the last lesson, you were able to update the sample app so it could filter between 3 different types of data: All Recipes, just Beverages, or just BakedGoods. While this provided the necessary functionality, it wasn’t the optimal implementation. Let’s look at how you can make more powerful queries.

Use Predicates to Filter Results

A @Query by itself, with no other filtering directives, will return all values. While this works for small amounts of data, larger sets of data are tougher to navigate for the user. Luckily, @Querys can support predicates.

@Query(filter: #Predicate<MyModel> { $0.name == "Iced tea" }, sort: \Recipe.name)
  var recipes: [Recipe]
Predicate<Recipe> predicate = #Predicate <Recipe> {
  // your conditional goes here
}
Predicate<Recipe> predicate = #Predicate <Recipe> {
  $0.name.contains("tea")
}
@Query var recipes: [Recipe]

init(predicate: Predicate<Recipe>?) {
  self.predicate = predicate
  if predicate != nil {
    _recipes = Query(filter: predicate, sort: \.name, order: .forward)
  }
}

Use Complex Predicates to Filter Across Multiple Properties

Databases typically provide multiple columns for each row, which translates to multiple properties for each object stored in a table. This means that queries should be able to search over multiple properties. If you’ve ever used SQL, or any similar database language, you’ve seen clauses like this:

SELECT * FROM table_name WHERE val < 5 AND otherVal > 100
Predicate<Recipe> predicate = #Predicate <Recipe> {
  $0.name.contains("tea") && $0.caffeinated == true
}
Predicate<Recipe> namePredicate = #Predicate <Recipe> {
  $0.name.contains("tea")
}

Predicate<Recipe> caffeinePredicate = #Predicate <Recipe> {
  $0.caffeinated == true
}

Predicate<Recipe> fullPredicate = #Predicate <Recipe> {
  namePredicate.evaluate($0) && caffeinePredicate.evaluate($0)
}

Limiting the Amount of Returned Values

Depending on your use case, you don’t need to return all the values of your query. For example, if you have a widget that just needs to show the next recipe on the schedule, you can restrict the number of returned values by setting the fetchLimit of a FetchRequest to 1:

fetchDesc.fetchLimit = 1
See forum comments
Download course materials from Github
Previous: Introduction Next: Predicates Demo