T
TypeDB•2w ago
Dixit Shah

Help with query

Hi I wonder if anyone can help. I'm relatively new to TypeQL. I have a simple schema like this: define entity sap_object, owns object_id, owns object_name, owns object_process, plays dependency:needs, plays dependency:is_needed_by; relation dependency, relates needs @card(0..), relates is_needed_by @card(0..), owns rel_keys, owns rel_type; attribute object_id, value string; attribute object_name, value string; attribute object_process, value string; attribute rel_keys, value string; attribute rel_type, value string;
36 Replies
georgii
georgii•2w ago
Hi! What is the latest query that you've tried to get the conjuncted result? Or does "all together" mean something else? Try rephrasing your vocal request. If you need "that it needs or is needed by", then this disjunction is the thing you need:
match
$object isa sap_object, has object_id "some_id";
$dep isa dependency;
{ $dep links (needs: $object, is_needed_by: $answer); } or { $dep links (is_needed_by: $object, needs: $answer); };
match
$object isa sap_object, has object_id "some_id";
$dep isa dependency;
{ $dep links (needs: $object, is_needed_by: $answer); } or { $dep links (is_needed_by: $object, needs: $answer); };
If you need "that it needs and is needed by at the same time", then it's just a conjunction without or branches (which you probably tried before).
Joshua
Joshua•2w ago
@Dixit Shah let us know if this works!
Dixit Shah
Dixit ShahOP•2w ago
@georgii I tried the query above but it didn't return any data back. What I am looking for is 2 queries. One that returns all the sap_objects that the given object "needs". The other query is one that returns all the sap_objects that the given object "is_needed_by".
Joshua
Joshua•2w ago
by the way do you have data inserted?
Dixit Shah
Dixit ShahOP•2w ago
Yes, have lots of data
georgii
georgii•2w ago
Can you try running these queries? 1.
match
$object isa sap_object;
match
$object isa sap_object;
2.
match
$object isa sap_object;
$dep isa dependency;
$dep links (needs: $object, is_needed_by: $answer);
match
$object isa sap_object;
$dep isa dependency;
$dep links (needs: $object, is_needed_by: $answer);
3.
match
$object isa sap_object;
$dep isa dependency;
{ $dep links (needs: $object, is_needed_by: $answer); } or { $dep links (is_needed_by: $object, needs: $answer); };
match
$object isa sap_object;
$dep isa dependency;
{ $dep links (needs: $object, is_needed_by: $answer); } or { $dep links (is_needed_by: $object, needs: $answer); };
Do they return answers?
Dixit Shah
Dixit ShahOP•2w ago
Let me try Ok 1. returns data i.e. list of internal object id's. 2. Does not return anything it says 0 rows. 3. Does not return anything either again it says 0 rows. The query below returns stuff: match $obj1 isa sap_object, has object_id "KD0017"; $obj2 isa sap_object; $dep isa dependency ($obj1, is_needed_by: $obj2); fetch { "obj1": {$obj1.}, "obj2": {$obj2.}, };
georgii
georgii•2w ago
What about
match
$object isa sap_object;
$dep isa dependency, links ($object);
match
$object isa sap_object;
$dep isa dependency, links ($object);
? And then
match
$object isa sap_object;
$dep isa dependency, links (needs: $object);
match
$object isa sap_object;
$dep isa dependency, links (needs: $object);
I suspect something is wrong with your roles, or you may actually have no data you are looking for
Dixit Shah
Dixit ShahOP•2w ago
This new query you listed above returns data.
georgii
georgii•2w ago
With the needs role specification or without it?
Dixit Shah
Dixit ShahOP•2w ago
Ok, without needs it returns 1382 rows. With the needs it returns 691 rows. exactly half which is want I would expect. *what
georgii
georgii•2w ago
If there are instances of dependency have role players of different roles, it means that the queries above should work. Try this, please:
match
$dep isa dependency, links (needs: $_, is_needed_by: $_);
match
$dep isa dependency, links (needs: $_, is_needed_by: $_);
Dixit Shah
Dixit ShahOP•2w ago
The above query with $_ returns 0 rows
georgii
georgii•2w ago
Thanks. So, if your queries are separate, it should be as simple as this: 1. One that returns all the sap_objects that the given object "needs"
match
$object isa sap_object, has object_id "some_id";
(is_needed_by: $object, needs: $answer) isa dependency;
match
$object isa sap_object, has object_id "some_id";
(is_needed_by: $object, needs: $answer) isa dependency;
2. The other query is one that returns all the sap_objects that the given object "is_needed_by"
match
$object isa sap_object, has object_id "some_id";
(needs: $object, is_needed_by: $answer) isa dependency;
match
$object isa sap_object, has object_id "some_id";
(needs: $object, is_needed_by: $answer) isa dependency;
But $dep isa dependency, links (needs: $_, is_needed_by: $_); returning zero answers shows that there are no such dependencies with two role players of different role types. You said that this query returned answers, right?
match
$obj1 isa sap_object, has object_id "KD0017";
$obj2 isa sap_object;
$dep isa dependency ($obj1, is_needed_by: $obj2);
match
$obj1 isa sap_object, has object_id "KD0017";
$obj2 isa sap_object;
$dep isa dependency ($obj1, is_needed_by: $obj2);
Can you try rerunning it (just to verify) and then also these two queries: One
match
$obj1 isa sap_object, has object_id "KD0017";
$obj2 isa sap_object;
$dep isa dependency (is_needed_by: $obj1, is_needed_by: $obj2);
match
$obj1 isa sap_object, has object_id "KD0017";
$obj2 isa sap_object;
$dep isa dependency (is_needed_by: $obj1, is_needed_by: $obj2);
Two
match
$obj1 isa sap_object, has object_id "KD0017";
$obj2 isa sap_object;
$dep isa dependency (needs: $obj1, is_needed_by: $obj2);
match
$obj1 isa sap_object, has object_id "KD0017";
$obj2 isa sap_object;
$dep isa dependency (needs: $obj1, is_needed_by: $obj2);
I'm trying to understand if it's just how your data is built or there is a bug
Dixit Shah
Dixit ShahOP•7d ago
Ok. So the query: match $obj1 isa sap_object, has object_id "KD0017"; $obj2 isa sap_object; $dep isa dependency ($obj1, is_needed_by: $obj2); Returned 24 rows of data as expected. The query: match $obj1 isa sap_object, has object_id "KD0017"; $obj2 isa sap_object; $dep isa dependency (is_needed_by: $obj1, is_needed_by: $obj2); Also returned 24 rows of data. It seems to return the same results as the above query. The query: match $obj1 isa sap_object, has object_id "KD0017"; $obj2 isa sap_object; $dep isa dependency (needs: $obj1, is_needed_by: $obj2); Returned 0 rows of data. Which is very strange. @georgii I'm happy to share the schema and data with you confidentially over e-mail if that helps
georgii
georgii•7d ago
Which means that, if a dependency has a is_needed_by role player, it does not have any needed role players. It is also supported by the results of this query I strongly suggest checking how you insert your data if you expected KD0017 to be in at least one dependency playing needs and having another is_needed_by object. If you don't find the bug there, yes, you can share it
Dixit Shah
Dixit ShahOP•7d ago
Ok, Let me have a look and come back to you either later or tomorrow. The data basically looks like this: $inbo17o19 isa dependency (is_needed_by: $o17, is_needed_by: $o19); $no19o17 isa dependency (needs: $o19, needs: $o17); $inbo17o27 isa dependency (is_needed_by: $o17, is_needed_by: $o27); $no27o17 isa dependency (needs: $o27, needs: $o17); $inbo17o56 isa dependency (is_needed_by: $o17, is_needed_by: $o56); $no56o17 isa dependency (needs: $o56, needs: $o17); $inbo17o117 isa dependency (is_needed_by: $o17, is_needed_by: $o117); $no117o17 isa dependency (needs: $o117, needs: $o17); $inbo17o40 isa dependency (is_needed_by: $o17, is_needed_by: $o40); $no40o17 isa dependency (needs: $o40, needs: $o17);
georgii
georgii•7d ago
Well, I can already see the issue. I misunderstood your usage. The query results are correct. We need to combine two relations. So, say, you have a relation $inbo17o56. It relates two instances: $o17 and $o56. Both of them are is_needed_by. How do you tell what object needs them in model yourself? It's impossible right now, the dependency instances are not related to each other You probably want to insert it like this: if obj1 needs obj2 and obj3, then
insert
$_ isa dependency (is_needed_by: $obj1, needs: $obj2, needs: $obj3);
insert
$_ isa dependency (is_needed_by: $obj1, needs: $obj2, needs: $obj3);
In case you want to group them by the object in need. For simplicity, I'd do this:
insert
$_ isa dependency (is_needed_by: $obj1, needs: $obj2);
$_ isa dependency (is_needed_by: $obj1, needs: $obj3);
insert
$_ isa dependency (is_needed_by: $obj1, needs: $obj2);
$_ isa dependency (is_needed_by: $obj1, needs: $obj3);
This way, the relation is binary and simple. Then, your schema can be made stricter and safer:
relates needs @card(0..1), # or @card(1)
relates is_needed_by @card(0..1), @card(1)
relates needs @card(0..1), # or @card(1)
relates is_needed_by @card(0..1), @card(1)
Currently, the intent is not too clear
Dixit Shah
Dixit ShahOP•7d ago
Ok what I was trying to achieve was where Obj1 'is needed by ' Obj2. And likewise Obj2 'needs' Obj1.
georgii
georgii•7d ago
Currently, with this
$inbo17o27 isa dependency (is_needed_by: $o17, is_needed_by: $o27);
$no27o17 isa dependency (needs: $o27, needs: $o17);
$inbo17o27 isa dependency (is_needed_by: $o17, is_needed_by: $o27);
$no27o17 isa dependency (needs: $o27, needs: $o17);
You just state that there is something that needs o27 and o17, and there is also something that is needed by o27 and o17
georgii
georgii•7d ago
It's probably just
$_ isa dependency (is_needed_by: $o17, needs: $o27);
$_ isa dependency (is_needed_by: $o17, needs: $o27);
Or vice versa. Right? You want to relate them. Our relations are labeled (role names), so you don't need to create two edges from 1 to 2 and from 2 to 1. A single relation does the job (and can even do much more!)
No description
Dixit Shah
Dixit ShahOP•7d ago
On the cardinality I can't have @card(1) as some objects have no 'is_needed_by' or 'needs' objects
georgii
georgii•7d ago
Do you want to introduce a relation, then? Isn't it just an object without dependencies? But you can make it just (needs: $o27), of course. I don't really think you need to produce unused data. Might be useful for some queries, though. It's up to you, I'm just flagging a potential issue with your model, which leads to this confusion with the data Schema constraints can help you organize everything very well, but it requires some time 🙂
Dixit Shah
Dixit ShahOP•7d ago
@georgii imagine a network diagram from left to right like: where I have objects dependent on one another. For example 'Business Partner: Supplier' is dependend on 'GL Accounts & Account Group'. I'm trying to represent this network an then be able to find all the object 'Business Partner: Supplier' is dependent on and also all the objects that are dependent on 'Business Partner: Supplier'. It looks like I've not defined this properly from what you're telling me.
No description
Dixit Shah
Dixit ShahOP•7d ago
Some objects like 'GL Accounts ....' don't have any dependencies to the left. Thus the cardinality issue.
georgii
georgii•7d ago
It won't be the issue if you resolve how you plan to represent the data Please reiterate this I will gladly help you figure it out. We can resolve your confusion step by step, if you want. First. What do inbo17o117 and no117o17 describe? Why do they exist?
Dixit Shah
Dixit ShahOP•7d ago
So 'inb' is 'is needed by' and 'o' is object. Similarly 'n' is 'needs' etc. So the idea was to have a variable that describes the role. I thought I'd defined a single relation 'dependency' with two roles 'needs' and 'is needed by'. I think what you're saying is that I've defined two relations right?
georgii
georgii•7d ago
Exactly. To create a single instance, you say isa dependency. Then, you add links (...) to it (isa dependency (...) is a shortcut). What you defined is one relation with two is_needed_by and one relation with two needs. Instead, you probably need a single relation with one is_needed_by and one needs. This picture is very similar do your diagram
georgii
georgii•7d ago
Say, here. KD0037 needs KD0018, I assume? Insert a rhombus inside the arrow between them. On one side, you'll have needs, and on the other side, you'll have is_needed_by. It's
$_ isa dependency (is_needed_by: $kd0037, needs: $kd0018);`
$_ isa dependency (is_needed_by: $kd0037, needs: $kd0018);`
(and I would call them needed and needs or is_needed_by and is_needed, it's a little easier to reason with)
No description
Dixit Shah
Dixit ShahOP•7d ago
@georgii got it! I effectively created two instances of a relation! Duh! Thank you. This has been so useful for understanding this a lot better. I definitely owe you a beer or two (that is if you drink!). And I agree needed and needs is easier to reason with.
georgii
georgii•7d ago
Very glad it helped! Feel free to use https://studio.typedb.com/ (connect to your instance using the 8000 port instead of 1729) and select the graph output to see real graphs. Insert some small portions of data and play around, the whole team enjoys this process 🙂
TypeDB Studio
TypeDB Studio enables software engineers to build data applications faster, with a modern language that avoids complexity.
Dixit Shah
Dixit ShahOP•7d ago
One more question if I have a variable $ and then I repeat the same variabe $ again but with a different assignment I assume it overwrites the original value i.e. $_ isa dependency (is_neededby: $KD0037, needs: $KD0017); $ isa dependency (is_neededby: $KD0037, needs: $KD0001); Then I assume the value of $ in the second line supercedes the first assignment i.e. I don't need a unique variable for each assignment right?
georgii
georgii•7d ago
Nope. You can check out this page https://typedb.com/docs/core-concepts/typeql/query-variables-patterns (and I generally recommend skimming everything to understand the language better; we tried not to overload you with sentences) for a detailed explanation. Simply speaking, both schema and data queries are declarative. When you declare your schema, you can say:
define entity person owns name;
define entity person owns name;
But can also say:
define
entity person;
person owns name;
define
entity person;
person owns name;
The fact that person owns name does not cancel the fact that person is also an entity. However, saying
define
entity person;
relation person;
define
entity person;
relation person;
will lead to an error because TypeDB does not understand you: person can be either an entity or a relation. The same works for data queries. The order does not matter, TypeDB can reorder your statements however it wants to achieve the most optimal execution path. You only describe your data: $KD0037 isa object, $KD0037 plays the needs role in $dependency0037, $KD0037 plays the is_needed_by role in $dependency0038, etc.
Dixit Shah
Dixit ShahOP•7d ago
Thank for clarifying. So if I understood you then the following would work: Insert $name isa person, has name 'John'; $name isa person, has name 'Fred'; ... In this case $name starts with a value of 'John' and then a reassignment happens and now $name is 'Fred' and TypeDB will first insert 'John' and then insert 'Fred' even though I'm using the same variable $name. Correct?
georgii
georgii•7d ago
No, no, completely the opposite. You declare what '$name' is, and you cannot "undeclare" or "redeclare" it. This query will try to insert a single person with two names (if I am not wrong, we will error because there are two 'isa' constraints, which is a sign of a user's mistake). When you insert, each variable represents an instance. Just like for defines, you can write
insert
$obj1 isa object;
$obj2 isa object, has name 'Alice';
$obj1 has name 'Bob';
insert
$obj1 isa object;
$obj2 isa object, has name 'Alice';
$obj1 has name 'Bob';
If we renamed $obj2 to $obj1 and your suggestion was right, how would you understand this query? That's one of the ways how to understand it. Another part is that every insert query also returns answers (just like match queries). Each raw insertion produces a single row of data, with each variable being bound to an instance. If a single variable was bound to multiple instances, there would be no way to fit it into a single row. I definitely recommend you playing around with a smaller dataset to understand these base concepts. With them, all the next steps should be much smoother 🙂
Dixit Shah
Dixit ShahOP•7d ago
Thanks for clarifying @georgii

Did you find this page helpful?