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

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;

Related

How to query rules in a TypeDB database?

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

How to query role types in a TypeDB relation?

Suppose I have the following in the schema:
define
person sub entity, plays employment:employee;
company sub entity, plays employment:employer;
employment sub relation, relates employee, relates employer;
Then it imposes the restriction that employer must be of type company and employee must be of type person.
How do I find about this restriction through a query?
So far the best that I know is:
match $x sub relation; get $x;
It does show that employment is a relation. But it doesn't show the role types that are allowed/ permitted. How to query that?
match $x sub relation;
$x relates $y;
get $x, $y;
You can use the same constructs for querying the schema (or data) as you did to write it. So you can also find which types play the roles through the query:
match $x sub relation;
$x relates $y;
$z plays $y;
get $x, $y, $z;

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.

Symfony2 - How to Dynamically get a Doctrine entity's Entity Manager

We are building a CMS and website building platform with a lot of different vendors and clients sites, so there are a lot of different content type entities, which are edited by generic controllers and helper services that don't necessarily (easily) know what the entity manager is for a given entity.
NOTE: We have several entityManagers to separate access to different databases, e.g. Global, Billing, Local, etc
There are many cases where we need to detect what is the entity's EntityManager. For example, we have a MediaHelper that dynamically associates media from a database with matching fields on the entity (this doesn't work with associations because the Media has to connect with literally any entity and you can't have that kind of dynamic association and we don't want a hundred different associations).
The media is in a bundle managed by the 'Local' EntityManager. But the entity may be in a 'Global' EntityManager (you can't assume it's in the same entity manager). So we need to detect and persist the right entity manager for the right entity.
So how do you recommend dynamically detecting the entityManager for an entity?
Original Custom Method
NOTE: the accepted answer is a much better solution. This is just here for archival purposes.
Here is a simple solution that works. But I don't know enough about Symfony and Doctrine to know if it's a bad idea? Does anyone else know? If not, I don't know why this wouldn't be in the core, as a Doctrine Utility.
I created an EntityHelper service that injects the Doctrine service into it:
gutensite_cms.entity_helper:
class: Gutensite\CmsBundle\Service\EntityHelper
arguments:
- "#doctrine"
Then in the entity helper is one simple function to get the Entity Manager for an entity (the config.yml registers the bundles for entity managers already):
/**
* Automagically find the entityManager for an entity.
* #param $entity
* #return mixed
*/
public function getManagerForEntity($entity) {
$className = \Doctrine\Common\Util\ClassUtils::getRealClass(get_class($entity));
foreach (array_keys($this->doctrine->getManagers()) as $name) {
if(in_array($className, $this->doctrine->getManager($name)->getConfiguration()->getMetadataDriverImpl()->getAllClassNames())) return $em;
}
}
NOTE: Doctrine Registry#getAliasNamespace already does something nearly identical to this foreach loop, I just modified the idea to return the entity manager instead of the namespace, e.g.
public function getAliasNamespace($alias) {
foreach (array_keys($this->getManagers()) as $name) {
try {
return $this->getManager($name)->getConfiguration()->getEntityNamespace($alias);
} catch (ORMException $e) {
}
}
throw ORMException::unknownEntityNamespace($alias);
}
Update 10/21/15: Entity Detection Code updated per #Cerad's suggestion.
Per the suggestion of #qooplmao, there is an easy method already in the Doctrine core.
// 1) get the real class for the entity with the Doctrine Utility.
$class = \Doctrine\Common\Util\ClassUtils::getRealClass(get_class($entity))
// 2) get the manager for that class.
$entityManager = $this->container->get('doctrine')->getManagerForClass($class);
Updated 10/22/15 After suggestions from Cerad and Qooplmao
Can you not give the entity manager a alias that suits the context it is for? You talk about Global, Billing, Local, so for example:
'service_manager' => array(
'aliases' => array(
'global_entity_manager' => 'My\Global\EntityManager',
'billing_entity_manager' => 'My\Billing\EntityManager',
'local_entity_manager' => 'My\Local\EntityManager',
),
)
You could also map the entity manager to the namespace of the entity.
So let's say you have a folder for your Global entities that is Global\Entity, then you could alias the entity manager for those entities Global\Entity\EntityManager. The advantage of this solution is that you can map several namespaces to the same entity manager, so your Billing and Global entities can easily share the same entity manager:
'service_manager' => array(
'aliases' => array(
'Global\Entity\EntityManager' => 'My\Global\EntityManager',
'Billing\Entity\EntityManager' => 'My\Global\EntityManager', // <-same name
'Local\Entity\EntityManager' => 'My\Local\EntityManager',
),
)
This only works if your entities in one namespace are manager by the same EntityManager instance. I can hardly believe this would not be the case in any project, but otherwise you should maybe reorganize a bit? :D

Symfony2 Application Architecture - how to make a function available in all controllers?

I'm building an application where users are tied to accounts (as in, multiple users all share an account), then other entities - lets call them products are tied to the accounts. The products are associated with the accounts and only users that are tied to that account can edit the products.
The difference being in my case, there are many different entities being shared in the same model.
If it was just the one (product) entity, it wouldn't be a problem to have a method in my ProductRepository like:
public function checkOwnership($id, $account)
{
$count = $this->createQueryBuilder('s')
->select('count(s.id)')
->where('s.account = :acc')
->andWhere('s.id = :id')
->setParameters(array('id' => $id, 'acc' => $account))
->getQuery()
->getSingleScalarResult();
if($count == 0)
throw $this->createNotFoundException('ye..');
return;
}
To make sure the id of the product is tied to the user's account.
The account argument is passed to this function by using:
$this->getUser();
In the controller.
What is the best way for me to make this function available to the other entities to prevent code duplication? There are (currently) only 3 other entities, so it wouldn't be the end of the world to just have it in each repository, but I'm just wondering if there were a way to create a 'common' or global repository that follows good standards? I'd sure like to know about it.
Edit:
Or have I just completely over-thought this? Can I just create a 'Common' directory in my 'MainBundle', define a namespace and add a use statement at the start of my controllers that need access to the function?
I hope I fully understand your question.
Solution one, duplication, easy: let #ParamConverter do the job (automatic response to 404 if doesn't exist)
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
/**
* #Route("/pets/{id}")
*/
public function showAction(Pet $pet)
{
// Current logged user
$currentUser = $this->get('security.context')->getToken()->getUser();
// Owner
$ownerUser = $pet->getUser();
if(!$currentUser->equals($ownerUser)) {
// 401, 403 o 404 depends on you
}
}
Solution two, DRY, a bit harder: use JMSAOPBundle and define an interceptor that intercepts all request to you controller and actions (show, delete, etc.). The pointcut (connected to the interceptor) will get the current user from the context and the owner from the entity. Then you do the check...

Resources