Hello there!
I want to run a conditional upsert as shown in the example below:
curl -H "Content-Type: application/rdf" -X POST localhost:8080/mutate?commitNow=true -d $'
upsert {
query {
# filter is needed to ensure that we do not get same UIDs in u1 and u2
q1(func: eq(email, "user_email1@company1.io")) @filter(not(eq(email, "user_email2@company1.io"))) {
u1 as uid
}
q2(func: eq(email, "user_email2@company1.io")) @filter(not(eq(email, "user_email1@company1.io"))) {
u2 as uid
}
q3(func: eq(email, "user_email1@company1.io")) @filter(eq(email, "user_email2@company1.io")) {
u3 as uid
}
}
# case when both emails do not exist
mutation @if(eq(len(u1), 0) AND eq(len(u2), 0) AND eq(len(u3), 0)) {
set {
_:user <name> "user" .
_:user <dgraph.type> "Person" .
_:user <email> "user_email1@company1.io" .
_:user <email> "user_email2@company1.io" .
}
}
# case when email1 exists but email2 does not
mutation @if(eq(len(u1), 1) AND eq(len(u2), 0) AND eq(len(u3), 0)) {
set {
uid(u1) <email> "user_email2@company1.io" .
}
}
# case when email1 does not exist but email2 exists
mutation @if(eq(len(u1), 0) AND eq(len(u2), 1) AND eq(len(u3), 0)) {
set {
uid(u2) <email> "user_email1@company1.io" .
}
}
# case when both emails exist and needs merging
mutation @if(eq(len(u1), 1) AND eq(len(u2), 1) AND eq(len(u3), 0)) {
set {
_:user <name> "user" .
_:user <dgraph.type> "Person" .
_:user <email> "user_email1@company1.io" .
_:user <email> "user_email2@company1.io" .
}
delete {
uid(u1) <name> * .
uid(u1) <email> * .
uid(u2) <name> * .
uid(u2) <email> * .
}
}
}' | jq
Throughtout the dgraph-js
library the only way I could run a Multiple Mutation Block with different conditions based on previous queries inside a single transaction would be to instantiate a mutation class with the objective of being able to apply a condition to each of the instantiated objects, given the fact that I can not apply more than one condition to a single mutation class with dgraph-js
.
Let me present you an example of my semantic view:
// Each element inside the array represents an Id of a dgraph node.
const arrayOfNodeIds = ['1230','1234','1245','1545'];
let query = ``;
let nquads = ``;
// I create the class intances that will enable me to make the transaction.
const mu = new dgraph.Mutation();
const req = new dgraph.Request();
arrayOfNodeIds.forEach(id => {
// I create a variable to store the element I find in the DB with the given ID.
query = query.concat(`\nelement${id} as var(func: eq(xid, ${id}))`);
// Then I proceed to update a property of the element found with another value.
nquads = nquads.concat(`\nuid(element${id}) <age> '18'`);
// Here, however, I could set the condtition to that mutation instance
// everytime the loop passes through the instace, to take into account a condition
// for every element.
//....................
// mu.setCond(`@if(eq(len(element${id}), 1))`);
//.....................
// But instead I would be replacing the condition every time I call the method,
// which would make me ignore all of the elements in the batch to conditionate
// the further mutation.
});
// Once I have my upsert ready, I will be able to make the transaction.
req.setQuery(`query{${query}}`);
mu.setSetNquads(nquads);
// Is not an option to pass the condition outside the for loop, since I need to make a condition
// for every element.
//.................................................
// mu.setCond(`@if(eq(len(element${id}), 1))`);
//................................................
// Very later I would submit my mutation list.
req.setMutationsList([mu]);
So, for the given capacity of the library, as far as I am concerned, the solution would be to create as many instances of the mutation class equals the length of the incoming array in order to apply conditions to every one of its mutations.
This would be a very expensive operation, and could not offer a very reliable solution.
I would appreciate it very much, if somebody has found a turn around for this, or if I have misread the js-dgraph
documentation and was not able to properly digest it.
Any contribution will be highly appreciated.
Happy Sunday!
dgraph version
v20.03.3