Writing Queries

While rules are used to infer new knowledge or take action, queries are used to ask questions about a rule session.

Queries are typically defined with defquery, which has the following structure:

defquery railroad diagram

A query has two major pieces:

  • A parameter definition, which allow callers to control the scope of the query when it is called. Parameters can be specified as symbols or keywords.
  • One or more conditions, which define the facts matching the query. These conditions are the same structure as a rule left-hand side.

A sample query looks like this:

(defquery get-promotions
  "Query to find promotions for the purchase."
  [?type] ;;; can also be specified using a keyword as :?type, but symbols are more idiomatic to specify bindings.
  [?promotion <- Promotion (= ?type type)])

A caller may then execute that query with arguments. So if we only wanted to find lunch promotions, we might perform the query like this:

(query session get-promotions :?type :lunch) ;;; the :?type value can also be specified as a symbol '?type, but keywords are more idiomatic to specify arguments.

Some queries may have no parameters. Queries return a sequence of results, with each result being a map of the a bound variable to its value. So the above query may return a sequence that looks like this:

[{:?type :lunch :promotion #example.Promotion{:type :lunch :name "A name"}}
 {:?type :lunch :promotion #example.Promotion{:type :lunch :name "Other Name"}}]

What’s next?