Execute a query for facts matching a template.
query<T, U>(
start: T,
preposition: Preposition<T, U>
): Promise<U[]>;
j.for
Query for successors of a fact. What is a successor? It's the opposite of a predecessor. If a person is the predecessor of a post, then a post is a successor of a person.
You don't want just any successor. You want those of a specific type with a specific relationship. Express this by writing a template function.
function postsByAuthor(a) {
return j.match({
type: 'Blog.Post',
author: a
});
}
const posts = await j.query(person, j.for(postsByAuthor));
Query for successors of successors.
You can find all the grandchildren of a fact by joining two queries together using then
.
function tagsForPost(p) {
return j.match({
type: 'Blog.Post.Tags',
post: p
});
}
const tags = await j.query(person, j
.for(postsByAuthor)
.then(tagsForPost));
The above can be combined into a single template function if desired.
function tagsForPostsByAuthor(a) {
return j.match({
type: 'Blog.Post.Tags',
post: {
type: 'Blog.Post',
author: a
}
});
}
const tags = await j.query(person, j.for(tagsForPostsByAuthor));
When a fact has many predecessors, use an array within the template function. Even though the template lists only one predecessor, the query will match if that predecessor is anywhere in the array.
function postTagsByTag(t) {
return j.match({
type: 'Blog.Post.Tags',
tags: [t]
});
}
const postTags = await j.query(tag, j.for(postTagsByTag));
Query for predecessor of successors. In other words, go down to children, and then back up to a different parent. Kind of like a step-mother query.
You need to explicitly state that the successor has
a field.
Once you do, you can use that field within the match.
function postForPostTag(pt) {
pt.has('post');
return j.match(pt.post);
}
const posts = await j.query(tag, j
.for(postTagsByTag)
.then(postForPostTag));