Upsert without @upsert tag creating two different nodes

Hi Team, Is @upsert tag is mandatory for upsert?
I am not using upsert tag but I have a trigram index and It’s creating two different nodes( two uuid) instead of single node and its linking, Though I am using conditional uspert : [@if(eq(len(child),0)].
Here is query.

routine 1

upsert{
	query{
		var(func: eq(product.swidtag,"ph09")) @filter(eq(type_name,"product")){
                product as uid
      }
		var(func: eq(product.swidtag,"Smart Opt2")) @filter(eq(type_name,"product")){
                        child as uid
      }
	}
	mutation {
	 set{ 
		uid(product) <product.swidtag> "ph09" .
		uid(product) <type_name> "product" .
		uid(product) <dgraph.type> "Product" .
		uid(product) <scopes> "m2" .
		uid(child) <product.swidtag> "Smart Opt2" .
		uid(child) <type_name> "product" .
		uid(child) <dgraph.type> "Product" .
		uid(child) <scopes> "m2" .
		uid(child) <product.child> uid(product) . 
	 }
	}
}

routine 2

upsert{
	query{
		var(func: eq(product.swidtag,"ph03")) @filter(eq(type_name,"product")){
                product as uid
      }
		var(func: eq(product.swidtag,"Smart Opt2")) @filter(eq(type_name,"product")){
                        child as uid
      }
	}
	mutation {
	 set{ 
		uid(product) <product.swidtag> "ph03" .
		uid(product) <type_name> "product" .
		uid(product) <dgraph.type> "Product" .
		uid(product) <scopes> "m2" .
		uid(child) <product.swidtag> "Smart Opt2" .
		uid(child) <type_name> "product" .
		uid(child) <dgraph.type> "Product" .
		uid(child) <scopes> "m2" .
		uid(child) <product.child> uid(product) . 
	 }
	}
}

It supposed to create 3 nodes { ph03", “ph09”, “smart Opt2”} where smart Opt2 has two linking edge one with “Ph03” and another with “Ph09”.

No, the upsert directive is used to prevent duplicate on the transaction exec. It isn’t related to Upsert Block, they just have a similar name.

I have run your queries, and they return just fine 3 nodes.

{
  "data": {
    "varg": [
      {
        "uid": "0x2711",
        "product.swidtag": "ph09",
        "type_name": "product"
      },
      {
        "uid": "0x2712",
        "product.swidtag": "Smart Opt2",
        "type_name": "product"
      },
      {
        "uid": "0x2713",
        "product.swidtag": "ph03",
        "type_name": "product"
      }
    ]
  }
}

What is the issue exactly?

Cheers.

Hi Michel,
yes, I am using transactions for the same, as these are executing in a concurrent manner by goroutines. And I am getting 4 nodes

{
  "data": {
    "products": [
      {
        "uid": "0xe4",
        "scopes": [
          "m3"
        ],
        "type_name": "product",
        "product.swidtag": "Smart Opt2"
      },
      {
        "uid": "0xe5",
        "scopes": [
          "m3"
        ],
        "type_name": "product",
        "product.swidtag": "ph03"
      },
      {
        "uid": "0xe6",
        "scopes": [
          "m2"
        ],
        "type_name": "product",
        "product.swidtag": "ph09"
      },
      {
        "uid": "0xe7",
        "scopes": [
          "m2"
        ],
        "type_name": "product",
        "product.swidtag": "Smart Opt2"
      }
    ]
  },

scenario
1.Though I am using conditional mutation ( via checking count of the node) so that transaction won’t create 2 nodes of “smart Opt2”.
2. Not using upsert tag but I have trigram index.

Does it mean I need to add an upsert tag if I am using transactions?

The Upsert Directive has to be used in the case you need to check uniqueness on the fly (in concurrent transactions, not “global”). I’m not sure about the relation with trigram index, perhaps it is a bug. In that case, share a complete code in a gist. So we can reproduce it or tell what is wrong in the code.

BTW, trigram index is just an index. Not sure what you mean by “but I have trigram index”. Can you clarify? to make sure if it is a bug or not.

If you need the Upsert Directive behavior, yes.

I think if you take care of avoiding concurrent mutations from your client, you don’t need the upsert directive - I mean, make sure you have control of those scenarios instead of relying on that directive. And the Upsert Block is recommended for general cases.