Skip to content

Bug with multi-level (nested bocks) in Upsert Block #4779

@MichelDiz

Description

@MichelDiz

What version of Dgraph are you using?

Latest

Have you tried reproducing the issue with the latest release?

Yes

What is the hardware spec (RAM, OS)?

N/A

Steps to reproduce the issue (command/config used to run Dgraph).

Mutation Sample

I added "dgraph.type" just to be sure.

{
  "set": [
    {
      "type": "node",
      "dgraph.type": "Node",
      "id": "0",
      "labels": ["Movie"],
      "properties": {
        "tagline": "Welcome to the Real World",
        "title": "The Matrix",
        "released": 1999,
        "dgraph.type": "Properties"
      }
    }
]
}
type Node {
  properties
  type
  id
  labels
  tagline
  title
  released
}

type Properties {
  tagline
  title
  released
}

Query example

{  
  movies(func: has(properties)) @filter(eq(type,"node")){
    type
    id
    labels
    dgraph.type
    properties {
      tagline
      title
      released
    }
      tagline
      title
      released
  }
}

Run the Upsert Block

upsert {
  query {
    movies(func: has(type)) @filter(has(properties)){
      v as uid
      Labels as labels
      properties {
        Title as title
        Released as released
        Tagline as tagline
      }
    }
  }
  mutation {
    set {
      uid(v) <migrationDone> "True" .
      uid(v) <title> val(Title) .
      uid(v) <dgraph.type> val(Labels) .
      uid(v) <released> val(Released) .
      uid(v) <tagline> val(Tagline) .
    }
  }
}

Expected behaviour and actual result.

This operation should be able to copy the values ​​in the variables of the nested block, "properties". Thus allowing a kind of "migration" using Upsert Block. This feature is also equivalent to "merge". Where we collect the values ​​of the nested block, we paste in the target node and delete the nested block right after.

With this "Hack" I was able to make it work

WARNING - This "hack" works mutation by mutation. Not Bulk Upsert. If you try to bulk upsert, it can get crazy results.

upsert {
  query {
    movies(func: has(type)) @filter(has(properties)){
      v as uid
      Labels as labels
      properties {
        Title as title
        Released as released
        Tagline as tagline
      }
    }
 me() {
    TitleMe as sum(val(Title))
    ReleasedMe as sum(val(Released))
    TaglineMe as sum(val(Tagline))
  }
  }
  mutation {
    set {
      uid(v) <migrationDone> "True" .
      uid(v) <title> val(TitleMe) .
      uid(v) <dgraph.type> val(Labels) .
      uid(v) <released> val(ReleasedMe) .
      uid(v) <tagline> val(TaglineMe) .
    }
  }
}

Just an Update

Testing the PR #4767 for this issue - but now creating a new node instead of update it (which is the goal of 4692, to just update instead of creating new ones). It works like that.

pay attention that this would work only with 1 to 1 operation. It won't work in 1 to many (like bulk upsert).

upsert {
  query {
    movies(func: has(type), first:1) @filter(has(properties) AND not has(migrationDone)){
     uid
      qID as id
      Labels as labels
      properties {
        Title as title
        Released as released
        Tagline as tagline
      }
    }
 me() {
    LabelsMe as sum(val(Labels))
    TitleMe as sum(val(Title))
    ReleasedMe as sum(val(Released))
    TaglineMe as sum(val(Tagline))
    qIDMe as sum(val(qID))
  }
  }
  mutation {
    set {
      _:New <migrationDone> "True" .
      _:New <id> val(qIDMe) .
      _:New <title> val(TitleMe) .
      _:New <dgraph.type> val(LabelsMe) .
      _:New <released> val(ReleasedMe) .
      _:New <tagline> val(TaglineMe) .
    }
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    Stalearea/upsertIssues related to upsert operations.dgraphIssue or PR created by an internal Dgraph contributor.kind/bugSomething is broken.status/acceptedWe accept to investigate/work on it.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions