# Queries Sworm provides a very simple API for safe data queries. A complete query looks like this: ``` swift .all .where() .sort(, ascending: ) .limit() .offset() ``` You can use any combination of `where` `sort` `limit` `offset`. We will not focus on limit/offset, so let's go straight to sorting and predicates. ## Predicates The most important part of any query is the search predicate. To generate it, you need to write a strongly typed expression like the following: `\T.count == 10 || \T.date > Date() && !(\T.id === [1, 2, 3])` *Note*: The `===` operator is an "IN" operation. This form of notation is very intuitive and fully corresponds to the logic that is usually used in classical conditional expressions: comparison operators (==,! =,>, <,> =, <=), logical operators (!, &&, ||) and so on. Comparison operations are applicable to those attributes whose target primitives support these operations, i.e. are Equatable and / or Comparable. Each of the operators calls the corresponding method (eg `>` <-> `greaterThan`) of the [Query](/Sources/Sworm/Requests/Query.swift) entity. In addition to operator-method pairs, `Query` contains methods for text queries (`beginsWith`, `endsWith`, and `contains`) for which there are no built-in operators. And they need to be used directly: `\T.count == 10 || Query.endsWith(\T.name, "foo")` You may have noticed that everywhere attribute keypaths are specified in their full form (with a type) and you cannot omit the type. This was done to help the compiler quickly parse predicate expressions - tradeoff between speed of compilation and verbosity. Queries in the CoreData are, of course, more complex - for example, aggregate functions of relations (@count), specifying indices (indexed:by:), etc. But in Sworm, type system usage is limited to attributes only. To prevent this limitation from becoming a problem, Sworm allows you to combine raw strings and swift expressions: `\T.id == 4 && !"foo.bars.@count > 0"` Since such queries are used much less often than exclusively attribute queries, this should not be a big problem. ## Sorting For sorting by attribute to be possible, the target primitive of the attribute must be Comparable. And that's all you need to know about sorting in Sworm. Example: ``` swift let query = Author .all .sort(\.name, ascending: true) .sort(\.age, ascending: false) ``` ## Example At the end i will give an example to make the picture very clear: ``` swift let query = T .all .where(\T.marker === ["a", "d"] || \T.amount > 10 || Query.endsWith(\T.name, "ex")) .sort(\.name) .limit(5) let result = try db.perform { ctx in try ctx.fetch(query).map { try $0.decode() } } ```