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
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:
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).@Dixit Shah let us know if this works!
@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".
by the way do you have data inserted?
Yes, have lots of data
Can you try running these queries?
1.
2.
3.
Do they return answers?
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.},
};
What about
?
And then
I suspect something is wrong with your roles, or you may actually have no data you are looking for
This new query you listed above returns data.
With the
needs role specification or without it?Ok, without needs it returns 1382 rows. With the needs it returns 691 rows. exactly half which is want I would expect.
*what
If there are instances of
dependency have role players of different roles, it means that the queries above should work.
Try this, please:
The above query with $_ returns 0 rows
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"
2. The other query is one that returns all the sap_objects that the given object "is_needed_by"
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?
Can you try rerunning it (just to verify) and then also these two queries:
One
Two
I'm trying to understand if it's just how your data is built or there is a bugOk. 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
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 itOk, 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);
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
In case you want to group them by the object in need.
For simplicity, I'd do this:
This way, the relation is binary and simple. Then, your schema can be made stricter and safer:
Currently, the intent is not too clearOk what I was trying to achieve was where Obj1 'is needed by ' Obj2. And likewise Obj2 'needs' Obj1.
Currently, with this
You just state that there is something that needs o27 and o17, and there is also something that is needed by o27 and o17
It's probably just
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!)

On the cardinality I can't have @card(1) as some objects have no 'is_needed_by' or 'needs' objects
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 🙂@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.

Some objects like 'GL Accounts ....' don't have any dependencies to the left.
Thus the cardinality issue.
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?
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?
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 diagramSay, 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
(and I would call them needed and needs or is_needed_by and is_needed, it's a little easier to reason with)
@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.
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.
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?
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:
But can also say:
The fact that
person owns name does not cancel the fact that person is also an entity. However, saying
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.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?
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
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 🙂
Thanks for clarifying @georgii