Family tree schema hasInverse issues

I am trying to model a family tree using Slash GraphQL

type Person {
 id: ID!
 name: String!
 children: [Person] @hasInverse(field: "parents")
 parents: [Person] @hasInverse(field "children")

At first, this started out fine, however when adding children (grandchildren) using a mutation in the API explorer, parents and children fields would get copies of other entities parent or child values, I was adding children to parents one at a time, but this still led to some strange behaviour and duplication.

Where am I going wrong? any details or reading I should be looking into

Could I have a look at your mutation (the code)

mutation addChild {
  updatePerson(input: {filter: {id: "0x453a"}, set: {children: [
{id: "0x453b"},
{id: "0x4541"}
]
}}) {
    numUids
  }
}

after this mutation added the children, I re-used the same mutation code but set the filter id to “0x453b” (child)

mutation addChild {
  updatePerson(input: {filter: {id: "0x453b"}, set: {children: {id: "0x4601"}}}) {
    numUids
  }
}

on querying the grand child, expect one parent id: “0x453b” but got both parent and uncle. :man_shrugging:

query MyQuery {
  getPerson(id: "0x4601") {
    id
    parents {
      id
      name
    }
  }
}

Result

"data": {
    "getPerson": {
      "id": "0x4601",
      "name": "TestGrandchild",
      "parents": [
        {
          "name": "DadTest",
          "id": "0x453b"
        },
        {
          "name": "UncleTest",
          "id": "0x4541"
        }
      ]
    }
  },

I can only assume that I may have miss clicked the UI to construct the mutation and created a set parent: children { }, it’s not consistent and I tried to reproduce it today but haven’t so far.

Is my dgraph schema correct for something like a family tree? What would be the correct / better way to model a family tree where relationships have attributes, such as married but divorced, biological parent vs current parent, adopter parent etc.

Using the schema of :

type Person {
 id: ID!
 name: String!
 children: [Person] @hasInverse(field: "parents")
 parents: [Person] @hasInverse(field: "children")
}

And performing an insertion of 4 objects → Grandparent (:older_adult:), Parent (:woman_curly_haired:), Child (:boy:), ParentSibling_0 (:woman_red_haired:) followed by adding the offspring-wise relationship as follows:
:older_adult: → :woman_curly_haired: → :boy:
…\ → :woman_red_haired:

And running a first degree query :

query FirstDegreeRelation {
  queryPerson {
    id
    name
    parents {
      id
      name
    }
    children {
      id
      name
    }
  }
}

I got the following (correct result) :

"data": {
    "queryPerson": [
      {
        "id": "0xc352",
        "name": "Grandparent",
        "parents": [],
        "children": [
          {
            "id": "0xc353",
            "name": "Parent"
          },
          {
            "id": "0xc355",
            "name": "ParentSibling_0"
          }
        ]
      },
      {
        "id": "0xc353",
        "name": "Parent",
        "parents": [
          {
            "id": "0xc352",
            "name": "Grandparent"
          }
        ],
        "children": [
          {
            "id": "0xc354",
            "name": "Child"
          }
        ]
      },
      {
        "id": "0xc354",
        "name": "Child",
        "parents": [
          {
            "id": "0xc353",
            "name": "Parent"
          }
        ],
        "children": []
      },
      {
        "id": "0xc355",
        "name": "ParentSibling_0",
        "parents": [
          {
            "id": "0xc352",
            "name": "Grandparent"
          }
        ],
        "children": []
      }
    ]
  }

Your schema is correct, however I think you might have done an accidental parent relationship between the uncle and the child. Try modelling your vertex edge relationships properly ( for eg: a person who’s been divorced will have a divorced [ID] subfield and an inverse relationship with the ID of the person he has divorced. Parents can have an enum subfield to cast them as either biological parenthood or adoptive parenthood, etc.)

1 Like