How to update only the first result of a match query in Typedb?

137 Views Asked by At

In the schema I have:

define
description sub attribute, value string;
task sub entity, has description;

Now I write the following two transactions into data:

insert
$a isa task;
$b isa task;

So the result of the query match $x isa task is as expected:

{ $x iid 0x826e80048000000000000000 isa task; }
{ $x iid 0x826e80048000000000000001 isa task; }
answers: 2, total (with concept details) duration: 4 ms

Now I want to insert description to only the first task. So I tried:

match $x isa task; limit 1; insert $x has description "Buy Milk";

But this results in an error:

[THW15] Invalid Thing Write: The thing variable '$x' cannot be inserted as a new instance without providing its type (isa).`

But if I tried:

match $x isa task; insert $x has description "Buy Milk";

then it would update both the tasks.

I can do the following:

match $x iid 0x826e80048000000000000000; insert $x has description "Buy Milk";

and it works!

But I wonder if there is a more elegant way to do this.

So question: How can I update the attribute of only the first result of a match in TypeDB?

2

There are 2 best solutions below

4
James Williams On

I think the fundamental problem you have is that you're inserting tasks without identifying them in any way. TypeDB does give you an iid under the hood, but it would be easier for you to reason about if you gave your own ID to each task at the point at which you create them.

With the above insert query, you get a single task and add a description to it. This could be any task, which makes the query not very useful unless you know every single one of your tasks has no description.

If you wanted to insert a task without adding a description just yet, you could add an ID in advance using the schema:

define
    description sub attribute,
        value string;
    id sub attribute, 
        value string;
    task sub entity, 
        owns id, 
        owns description;

and the query:

insert
$a isa task, has id "123456789";
$b isa task, has id "987654321";

These are examples, but you now have a way to identify each task rather than finding a random one and adding a description to it.

0
Spankied On

I believe you can accomplish this like so:

match $t isa task, has name $oldDescription limit 1;
delete $t has description $oldDescription;
insert $t has description "New Description";