How to keep uniqueness

I need to insert an entity that must have:

  • unique uuid predicate (string). Set only once
  • unique account predicate (string)

Using upsert I can verify that the uuid does not exist and than insert a new node.
But how do I verify that the account predicate does not exist in other nodes (not necessarily with the same uuid)?

Considered:

  1. Starting transaction
  2. Query for the UUID, if exist than abort
  3. Query for the account, if exist than abort
  4. Insert
  5. Commit

Or upsert with multiple queries??

Thanks

Sorry for pinging, but uniqueness is quite important.

After 3 days of browsing around I realized that transaction will not help to maintain uniqueness.
So I am left with upsert. But how can I verify that two predicates are unique?

Just a noob here, but I would do a conditional upsert with a multiple query block.

https://dgraph.io/docs/master/mutations/#conditional-upsert

Someone correct me if I’m wrong please.

1 Like

Yes, this worked for me.

Still not sure if both uuid and account need the upsert index. And if there is any other issue because of the combination of two different predicates.

Here is a working example:

upsert {
  query {
    idExist(func: eq(uuid, "4dad2587-8537-449f-a3df-786d2907261d")){
      u1 as uid
    }
    acountExist(func: eq(account, "an Account")){
      u2 as uid
    }
  }
  mutation @if(eq(len(u1), 0) and eq(len(u2), 0)){
    set {
      _:tnnt <uuid> "4dad2587-8537-449f-a3df-786d2907261d" .
      _:tnnt <account> "an Account" .
      _:tnnt <dgraph.type> "Whatever" .
    }
  }
}

Hi @mbn18,
Can you answer couple of my questions regarding your query:

  1. Do you want to update an account number to a given uuid (say uuid1) if that account number is already present for some other uuid (say uuid2)?
  2. Would your mutation always add a uuid and account or would you be possibly only updating account for a given uuid if that is already present?

Which index will you use for account and uuid predicates? It is suggested to use hash index as discussed here. Also both the predicates would require indexing since you will run eq operator on both of them.

I don’t foresee any issue because of the combination of two different predicates. Feel free to reach out if you get stuck somewhere.

No, account must be unique across all nodes (its like username. An easy abbreviation of customer name).

Current planing is that uuid will be immutable while account can be updated. We would however seperate Add from Update. So this upsert/mutate will take care of the Add procedure.

uuid -> hash as discussed here
account -> exact

Cool, I don’t foresee any problem with the proposed query. Like I said you’d need two indexes to make two sub-queries. Indexing can take place in background while you serve queries.

What I am still not sure about, do I need to add the upsert index to both predicates?

Yes, you would need it on both the predicates to avoid race conditions. Tagging @pawan who is an expert on this.

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.