How to do an upsert block with multiple linked variable from separate query blocks

Bulk Upsert is not highly recommended for everyone. In that case, you need to know how to control collateral damage when using such a procedure. My recommendation is to limit this query to one operation at a time.

For example, add a temporary predicate stating that there was a migration. e.g. “<migrated>” and add the check @filter (NOT has (<migrated>)) to your query. That way you avoid messing things up.

To limit one operation at a time, you must use the “first” paging parameter.

e.g

addresses(func: has(Address.tempCountry), first: 1) @filter(NOT has(<migrated>))

...
set {
      uid(address_uid) <Address.country> uid(country_uid) .
      uid(address_uid) <migrated>  "" .
      uid(country_uid) <Country.usedBy> uid(address_uid) .
    }

I would also separate the delete operation for later. I would add a “<to_be_deleted> "Address.tempCountry" . ” predicate and later I would delete them all via upsert block. Just to avoid deleting important data unintentionally.

I didn’t cover every part of the problem, as I didn’t fully understand it. If you provide a sample exemplifying the problem in practice, I may be able to go deeper. But in general, Bulk Upsert does not work in all cases.

Let me know if you have more questions.

Cheers.

2 Likes