How to query rules in a TypeDB database? - vaticle-typedb

In my schema I think I defined this rule:
define rule transitive-hierarchy-rule:
when {
(before: $a, after: $b) isa hierarchy;
(before: $b, after: $c) isa hierarchy;
} then {
(before: $a, after: $c) isa hierarchy;
};
Notice from the documentation:
"facts defined via rules are not stored in the knowledge graph. [...]
However, by defining the rule in the schema, at query time the extra
fact will be generated."
Also notice from the documentation:
Currently, for a match query to trigger reasoning and obtain
inferences from rules, you must use a read transaction. We are working
towards enabling reasoning in write transactions in subsequent
releases.
However in my query match (before: $x, after: $y) isa hierarchy inside a read transaction doesn't return the expected results:
{ $x iid 0x826e800b8000000000000000 isa task; $y iid 0x826e80048000000000000002 isa task; }
{ $x iid 0x826e800a8000000000000000 isa task; $y iid 0x826e800b8000000000000000 isa task; }
The above two results I had explicity defined. I was expecting the third result to be inferred via the rule.
So I am trying to debug the situation. Could it be possible that I did not define the rule properly?
So question: how do I query more about the rules that have been defined in the database schema?

Have you been sure to turn on inference? The 'infer' option must be turned on for rules to be triggered whilst running queries.
See the infer option for the java client API: https://docs.vaticle.com/docs/client-api/java#options

Related

Query inner elements based on role in grakn

I have a keyspace name 'server' in grakn with one entity named 'node' having an attribute "name". This keyspace is having only one relation named 'node_relation' that connects entities. The entity node acts the role as 'base' and 'dependent' in the node_relation.
This graph is aligned in such a way that all the elements in the left side are acting as base and right side act ad dependent in the node_relation.
I need to query nodes that act as base node for an entity and if the queried node has any node that is acting as a base node, I need to get it also until the queried node is not having any nodes with role base.
For example, if I want all nodes with role base for node named "F", I should get the answer as of "A,B,C,D,E,DD,EE,FF,XX,YY,ZZ".
Currently i am using the query
match $x isa node, has name "F";$y isa node;$rel(base:$x,$y);get $y;**
This query return E and DD as result and i will execute this query until a node is not having any node with role base.
Is their any some way to get all the node in a single query ?
Disclaimer: I'm pretty new to Grakn still.
The kind of relation you are looking for is transitive (if a->b and b->c then a->c). You can use Grakn rules to model this relation then use it in your query; Grakn infers the transitive relation when you execute the query.
Here's how I wrote the rules, include this in your schema.gql:
node_superrelation sub relation,
relates base,
relates dependent;
node-relation-is-superrelation-rule sub rule,
when {
(base: $a, dependent: $b) isa node_relation;
},
then {
(base: $a, dependent: $b) isa node_superrelation;
};
node-superrelation-is-transitive-rule sub rule,
when {
(base: $a, dependent: $b) isa node_superrelation;
(base: $b, dependent: $c) isa node_superrelation;
},
then {
(base: $a, dependent: $c) isa node_superrelation;
};
Now you can use the following query to get all bases of node F. Note that we specifically request those related by a node_superrelation.
match $d isa node, has name "F";$b isa node; $rel(base:$b,dependent:$d) isa node_superrelation;get $b;
You could make node_relation transitive and achieve this in one rule, but then queries using node_relation of F would always include all of the results without using a limit, which is probably not what you want. You could also define new roles for node_superrelation, which may also further simplify things, or use the shared roles to some other advantage. Hopefully, you can see that Grakn's rules are really very powerful and should let you describe these kinds of relations in a way that makes sense for your model!
Hope this helps!
EDIT: Just to add quickly that the convention in Grakn is to use hyphens rather than underscores.

Is there a way to 'get' all connected entities and their attributes connected to a specific instance of an entity?

I want to display all the data points for a specific instance of an entity.
I understand how to write the query in a specific form but I want it to be more general and be more concise.
This is what I currently have:
match
$t isa technology, has version "v9.5";
$as isa app-server, has database-server $ds, has dot-net-network $dnn, has XXXXXX $x1, has XXXXXX $x2;
$ds isa database-server, has XXXXXX $x3, has XXXXXX $x4;
$r1(container: $t, containee: $as);
$r2(container: $t, containee: $ds);
get; offset 0; limit 30;
There are several more entities connecting to my container.
In general in Graql we can make ambiguous queries by providing less constraints in the query, or changing a constraint to a more relaxed one.
In your case, I believe you want to ask a question specifically about an entity instance, described by this pattern: $t isa technology, has version "v9.5";. You want to find the entities it is connected to via a relation. You then wish to find all of the attributes of those connected entities, but without specifying all of the types of attribute those entities could own according to the schema.
The most generic way to get the connected concepts is:
match
$t isa technology, has version "v9.5";
$r($t, $e);
get $e;
If you want connected entities only:
match
$t isa technology, has version "v9.5";
$r($t, $e);
$e isa entity;
get $e;
This is because all of your user-defined entities inherit from entity. You can do the same for relation and attribute, or thing which is the super type of all three.
The full answer to get all of the attributes of a concept, is to use the same principal, giving the base type attribute:
match
$t isa technology, has version "v9.5";
$r($t, $e);
$e isa entity, has attribute $a;
get $e, $a;
Bonus
You can then find attributes common to two patterns, in this case two technology instances:
match
$t1 isa technology, has version "v9.5";
$e1 isa entity, has attribute $a;
$r1($t1, $e1);
$t2 isa technology, has version "v9.6";
$e2 isa entity, has attribute $e;
$r2($t2, $x2);
get $a;

How to list collections/resources recursivelly in XQuery

I would like to list all collections from a particular point recursively:
declare function local:list-collections($collection as xs:string) {
for $child in xmldb:get-child-collections($collection)
return
local:list-collections(concat($collection, '/', $child))
};
local:list-collections('/db/apps/tested-bunny/data/')
This returns nothing (no errors, no results). I am inspired by this article and consider it as a good starting point for recursive setting of permissions and so on.
See the dbutil:scan-*() functions in Wolfgang Meier's article on higher order functions with XQuery in eXist-db 2.0+. The article is very instructive article in general. These days the dbutil module is available in the shared-resources package that is installed by default with eXist, so you can make use of it as follows:
xquery version "3.0";
import module namespace dbutil="http://exist-db.org/xquery/dbutil"
at "/db/apps/shared-resources/content/dbutils.xql";
dbutil:scan-collections(
xs:anyURI('/db'),
function($collection) { $collection }
)
These functions perform well. I just ran this in eXide and the query returned 4125 collection names in 0.699s.
Your query does actually recursively find collections, but there is no output. I'd suggest to do something like
declare function local:list-collections($collection as xs:string) {
for $child in xmldb:get-child-collections($collection)
let $childCollection := concat($collection, '/', $child)
return
(local:list-collections($childCollection), $childCollection)
};
local:list-collections('/db/apps/fundocs')
But for sure Joe's suggestion is much cleaner.

SonataAdminBundle preload SQL objects

When using SonataAdminBundle, I am trying to visualize the leaf nodes of a database. My tables are A -> B -> C (-> = contains some). The leaf nodes I try to visualize is C.
C has a __toString() which will call B.__toString(), which in turns calls A.__toString().
The problem: I end up showing 30 lines and making 700 calls to the database.
Sometimes, I can avoid this problem by adding a filter, so it would make a request with the filter first and would "preload" some objects, but in this case, I can't add a filter as such.
Is there a way to preload my objects beforehand? The answer would probably contain 2 parts:
Where in Sonata should I do this?
What code should I execute to preload a hierarchy of objects which would minimize the amount of calls to the database?
You should override method createQuery where you can place your custom joins.
Example:
<?php
namespace Acme\DemoBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
class CarAdmin extends Admin
{
public function createQuery($context = 'list')
{
$query = parent::createQuery($context);
$query->leftJoin($query->getRootAlias . '.Model', 'mo');
$query->leftJoin('mo.Make', 'ma');
return $query;
}
}
Remember that, createQuery method returns Sonata ProxyQuery object, not Doctrine Query. So you should operate on query returned by Admin::createQuery.

How to use multiple filters to widen the search in Apachesolr queries

Making a search with Apachesolr, i want to add a couple of filters in hook_apachesolr_prepare_query(&$query). This works fine, except I want the filters to widen the search ('OR'), rather than narrow it ('AND').
For example, if I have 4 nodes of type:A and 3 of type:B that match a search, to filter by type:A and type:B should return 7 nodes (of type:A AND nodes of type:B), rather than 0 those of type:A which are also of type:B.
I saw a suggestion to do this using the model of nodeaccess
foreach ($filters as $filter) {
$subquery = apachesolr_drupal_query();
if (!empty($subquery)) {
$subquery->add_filter('type', $filter);
$query->add_subquery($subquery);
}
}
but this doesn't seem to work. (It doesn't return any results).
I then tried (as I have a limited number of node types) excluding the types that I don't want:
$excludes = array('A', 'B', 'C');
$excludes = array_diff($excludes, $filters);
$exclude = implode('&', $excludes);
$query->add_filter('type', $exclude, TRUE);
This method of stitching them together doesn't work (the '&' gets escaped) but neither does adding them as subqueries, similar to the manner above.
Any suggestions on how to do this?
With Drupal7 and the last apacheSolr API, you can do OR filters by doing this :
function my_module_apachesolr_query_alter($query) {
// first, create a subQuery filter to store others
// and specify there is a "OR" condition
$filter = new SolrFilterSubQuery('OR');
// next, add all filters on bundle you want, each as
// a new subQuery filter, always with "OR" condition
// and add it to the primary filter
$a = new SolrFilterSubQuery('OR');
$a->addFilter('bundle', 'A');
$filter->addFilterSubQuery( $a );
$b = new SolrFilterSubQuery('OR');
$b->addFilter('bundle', 'B');
$filter->addFilterSubQuery( $b );
$c = new SolrFilterSubQuery('OR');
$c->addFilter('bundle', 'C');
$filter->addFilterSubQuery( $c );
// finally, add the primary subQuery filter as
// subquery of the current query
$query->addFilterSubQuery( $filter );
}
And your query search about type A OR type B OR type C (all results in each types). You can combine OR / AND by changing the parameter of the SolrFilterSubQuery instanciation.
Special thanks to this page and it's author : http://fr.ench.info/blog/2012/04/03/Add-Filters-ApacheSOLR.html
I havenť played with SOLR much but I am quiete familiar with Drupal and Zend Lucene (or Drupal Lucene API).
I would suggest that you try to filter your results based on content type (because each node has its content type stored in the object).
The second idea is to change basic operator. I am not sure how it is done in SOLR but i Zend Lucene
Zend_Search_Lucene_Search_QueryParser::setDefaultOperator($operator) and Zend_Search_Lucene_Search_QueryParser::getDefaultOperator() methods, respectively.
Docs can be found in Zend Lucene Docs. Or for SOLR Solr Docs.
I hope a got your problem right.
Hope it helps :-)

Resources