Fork me on GitHub

Query on queries: I’d like to find all the facts in the session of type MyFact, where myfact looks like this: #MyFact{:stuff #{{:a 1} {:b #AnotherFact{:c true}}}


I’d only like to find MyFact where #AnotherFact{:c true}


It’s unclear to me how parameterization of queries works. I have an arg :?foo to the query which is a keyword, but it does not correspond to a field on the fact.


Query parameters just check for equality on a bound variable. So to query on a value in a nested structure, you'll need to bind that value itself to a variable. You can do this by just having an expression on the left-hand side that gets the nested field, e.g. (= ?foo (some-expr-to-get-a-value this).


@ryanbrush ok that makes sense, but what if I need the parameter as an argument to the expr that retrieves a value?


(= ?foo (get-in [:a ?foo :b] some-declared-field-on-the-toplevel-record))


where ?foo is the parameter (defquery myquery [:?foo] …)


Yeah, queries only do equality checks on bound variables. You could either bind all combinations of the nested path if it's small enough, or have your query return more than you need and filter it out afterwards, or consider other ways to model the data. Not sure what would work best for your model.


@ryanbrush ok, that’s kind of where i guessed we were heading. though i dont totally grok the binding of all combinations of the nested path.


the use case is that there’s a blob of :contributing-facts that gets populated by a big collection of prior rules firing, and i want to write a query that finds all of the facts where the thing that contributed is :x. short of writing a ton of queries, or generating them dynamically, i’m not sure that changing the model will help much. this is the typical “let’s have one place where we can dump a grab bag of metadata”


Yeah, I suspect having a function that scans query results, or finding another way to bind your additional criteria, would be your best bet.


@ryanbrush thanks for the help