In the Initializing Cascalog and Hadoop for distributed processing recipe, we looked at how to query data in Cascalog with a couple of small examples. However, Cascalog's query language is much more powerful than what we saw here. We'll dive in further in this recipe and start looking at some of the logical predicates available. Recipes in the later part of this chapter will have still more examples of querying with Cascalog.
For this recipe, we'll need the project.clj
dependencies and imports from the Initializing Cascalog and Hadoop for distributed processing recipe. We'll also use the data from that recipe: the sequences of information about the companions and actors from the British television program Doctor Who.
(?<- (stdout) [?n ?actor ?period] (actor ?n ?actor ?period) (<= ?n 5)) … RESULTS ----------------------- 1 William Hartnell 1963–66 2 Patrick Troughton 1966–69 3 Jon Pertwee 1970–74 4 Tom Baker 1974–81 5 Peter Davison 1981–84
(?<- (stdout) [?companion] (doctor ?companion ?n) (= ?n 10)) … RESULTS ----------------------- sarahjane rose jack mickey donna martha astrid jackson rosita christina adelaide wilfred
Well, he's a popular guy.
Let's take a look at the second example in a little more detail.
(?<- (stdout) [?companion] (doctor ?companion ?n) (= ?n 10))
The predicates are evaluated once for each row in the input data. Once a name has been bound to one predicate, it will keep that value throughout all the predicates. Moreover, a row is only output when all the predicates pass.
(?<- (stdout) [?companion] (doctor ?companion ?n) (= ?n 10))
This predicate only passes where ?n
is bound to 10. Since all the predicates have to pass successfully, this only returns the companions for Doctor number 10.
Variable binding, which we saw in this recipe, is a well-known feature of data-oriented systems. Prolog (http://www.learnprolognow.org/), for example, uses it extensively.