How to insert relations between entities via Loader.add()?


#1

Hello,

in “Slow performances writing data [SOLVED]” @alex shows how to use the Loader interface to insert multithreaded transactions to load tons of entities.

What is the correct syntax in order to also insert relations?

TIA,
Antonio


#2

Hi Antonio!

The Loader class takes in Inserts, which can contain relations as well as instances.

The following is valid:

    Loader loader = new LoaderImpl("bio");

    Var instance1 = var().isa("gene");
    Var instance2 = var().isa("gene");

    Var relation = var().rel(instance1).rel(instance2);

    loader.add(insert(instance1, instance2, relation));
    loader.flush()
    loader.waitToFinish();

One warning: You need to make sure that the instances you are relating already exist in the graph before adding the relations. If you insert all the vars in one add method, as I did above, they are guaranteed to be committed in one transaction/insert- you do not need to worry about order.

But because the loader is multithreaded, we cannot guarantee that the add methods are actually executed sequentially. This would throw an error:

    //THIS IS BAD - NOT ACTUALLY VALID

    Loader loader = new LoaderImpl("bio");

    Var instance1 = var().isa("gene");
    Var instance2 = var().isa("gene");

    Var relation = var().rel(instance1).rel(instance2);

    loader.add(insert(instance1));
    loader.add(insert(instance2));
    loader.add(insert(relation));

    loader.flush()
    loader.waitToFinish();

Just make sure that all the vars who acknowledge one another are in the same transaction.

Hopefully this helps!

Alexandra


#3

Hi Alexandra,

explanation clear and effective, as usual. You’re simply great!

I have had a little problem when I tried to insert all the anonymous vars together:

java.lang.UnsupportedOperationException: Graql strings cannot represent a query with inner variables

But it works when I specify all the names.

Again, thanks!

Antonio


#4

Hi Antonio,

Alexandra’s query has accidentally using “inner variables” (such as instance1 inside relation). This is fine in the Java Graql, but we don’t currently support it in the native Graql syntax. You can avoid the problem by using variable names:

Loader loader = new LoaderImpl("bio");

Var instance1 = var("instance1").isa("gene");
Var instance2 = var("instance2").isa("gene");

Var relation = var().rel("instance1").rel("instance2");

loader.add(insert(instance1, instance2, relation));
loader.flush();
loader.waitToFinish();