# Can new Edges be added to large numbers of existing Nodes by referencing a Node's Type?

**URL:** <https://discuss.dgraph.io/t/can-new-edges-be-added-to-large-numbers-of-existing-nodes-by-referencing-a-nodes-type/17566>\
**Category:** Dgraph\
**Tags:** dgraph\
**Created:** [July 24, 2022, 6:54am UTC](https://discuss.dgraph.io/t/can-new-edges-be-added-to-large-numbers-of-existing-nodes-by-referencing-a-nodes-type/17566 "2022-07-24T06:54:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![nick-walt](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/nick-walt/32/9896_2.png) [@nick-walt](https://discuss.dgraph.io/u/nick-walt)\
**Post date:** [July 24, 2022, 6:54am UTC](https://discuss.dgraph.io/t/can-new-edges-be-added-to-large-numbers-of-existing-nodes-by-referencing-a-nodes-type/17566/1 "2022-07-24T06:54:20Z")

</div>

If our application’s functional design changes over time to better model the domain and we want to add new Edges to large numbers of existing Nodes is it possible to add them to a Node’s “type” which will then be applied to existing and future Node instances by the database?

Or would we just tell the database to find all specific Node instances and then add the new Edges in a bulk update? Thanks!

---

<div class="post-metadata">

**Author:** ![matthewmcneely](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/matthewmcneely/32/4774_2.png) [@matthewmcneely](https://discuss.dgraph.io/u/matthewmcneely)\
**Post date:** [July 24, 2022, 5:21pm UTC](https://discuss.dgraph.io/t/can-new-edges-be-added-to-large-numbers-of-existing-nodes-by-referencing-a-nodes-type/17566/2 "2022-07-24T17:21:35Z")

</div>

Hi Nick,

Adding edges to established node types is something quite common in dgraph (and other graph databases). But there’s a distinction to be made: 1. defining a new edge and 2. assigning values to that new edge.

Say, for instance, your application has a Movie type with an [Actor] edge. Later you want to add a [Director] edge. No, problem — just update your schema with the new edge. Of course, at that moment all the existing Movie nodes will have empty [Director] edges. You’ll need to go back and update those nodes with the correct data.

Did I understand your question correctly?

---

<div class="post-metadata">

**Author:** ![MichelDiz](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/micheldiz/32/11873_2.png) [@MichelDiz](https://discuss.dgraph.io/u/MichelDiz)\
**Post date:** [July 24, 2022, 10:01pm UTC](https://discuss.dgraph.io/t/can-new-edges-be-added-to-large-numbers-of-existing-nodes-by-referencing-a-nodes-type/17566/3 "2022-07-24T22:01:53Z")

</div>

> [@nick-walt](#):
>
> “type”

Types in Dgraph isn’t all that “strict”. Types are basically a kind of “convention” and used to “reveal” the format of the node. So, you can even add “hidden” edges that only who queries knows it. What I mean is that, there’s no implications changing the schema over time.

Only GraphQL you are obligated to do things.

> [@nick-walt](#):
>
> and then add the new Edges in a bulk update

You mean upsert bulk update right? there’s no correlation there. Bulk update is a good way to update a database that changes over time.

---

<div class="post-metadata">

**Author:** ![nick-walt](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/nick-walt/32/9896_2.png) [@nick-walt](https://discuss.dgraph.io/u/nick-walt)\
**Post date:** [July 25, 2022, 9:26am UTC](https://discuss.dgraph.io/t/can-new-edges-be-added-to-large-numbers-of-existing-nodes-by-referencing-a-nodes-type/17566/4 "2022-07-25T09:26:18Z")

</div>

@matthewmcneely@MichelDiz

Hi Mathew and Michael. Thanks for your responses.

> [@matthewmcneely](#):
>
> Say, for instance, your application has a Movie type with an [Actor] edge. Later you want to add a [Director] edge. No, problem — just update your schema with the new edge. Of course, at that moment all the existing Movie nodes will have empty [Director] edges. You’ll need to go back and update those nodes with the correct data.

Does this mean that Edges can be like a type wrapper for the Node to which it points? Where a Director Edge (from a Movie Node) points to a Person, thereby saying that that person is a type Director? Elsewhere in the graph another Edge from a Person Node could point to the same Person Node, that the Director Edge points to, with a label of Father. This means that the same Person can be a different type within each relationship (Movie \> Director \> Person) and (Person \> Father \> Person)?

This seems to be very different compared to my experience with Types, which comes from an Algebraic Data Type (AlgDT) system… Or is it?

A Person type that is also a Director and a Father could be expressed as a Type with Variants:

```auto
type Person
    = Director
    | Father

```

Depending on the function that Person is either a Director or a Father? This is awesome! Is this why Neo4J mandates that all Edges are strictly typed?

Algebraic thinking reasons about values in terms of their types and the operations that can be applied to them by expressions (functions). These types can be directly associated to a domain entities.

The AlgDT type system comes from ML Functional Programming languages like Haskell, OCAML, Rescript (ReasonML), F#, Rust, Elm and to a limited extent Typescript.

Most AlgDTs are user-made custom types, like userProfile or UserID, and are recognised by the compiler and application as semantically unique entities and are assigned the same level of significance as that given to a string, integer record and array.

Algebraic Data Types can be understood as user-constructed types made up of single or multiple values that become entities in data. This means they can be composed in all sorts of cool ways and passed from one function to another, or nested inside other unique types.

AlgDTs are assigned a much higher level of uniqueness and meaning than conventional reference types which are primitive types with a label. Here is a quote from: [domain driven design - Is it still valid to speak about anemic model in the context of functional programming? - Software Engineering Stack Exchange](https://softwareengineering.stackexchange.com/questions/317587/is-it-still-valid-to-speak-about-anemic-model-in-the-context-of-functional-progr/317599#317599)

> Suppose we need to define a type representing user IDs. An “anemic” definition would state that user IDs are strings. That’s technically feasible, but runs into huge problems because user IDs _aren’t_ used like arbitrary strings. It makes no sense to concatenate them or slice out substrings of them, Unicode shouldn’t really matter, and they should be easily embeddable in URLs and other contexts with strict character and format limitations.

> Solving this problem usually happens in a few stages. A simple first cut is to say “Well, a `UserID` is represented equivalently to a string, but they’re _different types_ and you can’t use one where you expect the other.” Haskell (and some other typed functional languages) provides this feature via `newtype`:

```auto
newtype UserID = UserID String

```

> This defines a `UserID` function which when given a `String` constructs a value that is _treated like_ a `UserID` by the type system, but which is still just a `String` at runtime. Now functions can declare that they require a `UserID` instead of a string; using `UserID`s where you previously were using strings guards against code concatenating two `UserID`s together. The type system _guarantees_ that can’t happen, no tests required.

> The weakness here is that code can still take any arbitrary `String` like `"hello"` and construct a `UserID` from it. Further steps include creating a “smart constructor” function which when given a string checks some invariants and only returns a `UserID` if they’re satisfied. Then the “dumb” `UserID` constructor is made private so if a client wants a `UserID` they _must_ use the smart constructor, thereby preventing malformed UserIDs from coming into existence.

> Even further steps define the `UserID` data type in such a way that it’s _impossible_ to construct one that’s malformed or “improper”, simply by definition. For instance, defining a `UserID` as a list of digits:

```auto
data Digit = Zero | One | Two | Three | Four | Five | Six | Seven | Eight | Nine
data UserID = UserID [Digit]

```

> To construct a `UserID` a list of digits must be provided. Given this definition, it’s trivial to show that it’s impossible for a `UserID` to exist that can’t be represented in a URL. Defining data models like this in Haskell is often aided by advanced type system features like [Data Kinds](https://downloads.haskell.org/~ghc/7.6.2/docs/html/users_guide/promotion.html) and [Generalized Algebraic Data Types (GADTs)](https://wiki.haskell.org/Generalised_algebraic_datatype), which allow the type system to define and prove more invariants about your code. When data is decoupled from behavior your data definition is the only means you have to enforce behavior.

---

<div class="post-metadata">

**Author:** ![MichelDiz](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/micheldiz/32/11873_2.png) [@MichelDiz](https://discuss.dgraph.io/u/MichelDiz)\
**Post date:** [July 25, 2022, 2:23pm UTC](https://discuss.dgraph.io/t/can-new-edges-be-added-to-large-numbers-of-existing-nodes-by-referencing-a-nodes-type/17566/5 "2022-07-25T14:23:09Z")

</div>

> [@nick-walt](#):
>
> Depending on the function that Person is either a Director or a Father?

You can give several Type names for a single node(person + father) if you want to. The edge in general just link nodes. For example Jorge is a person and has an edge “Director of” xyz.

---

<div class="post-metadata">

**Author:** ![matthewmcneely](https://yyz1.discourse-cdn.com/flex007/user_avatar/discuss.dgraph.io/matthewmcneely/32/4774_2.png) [@matthewmcneely](https://discuss.dgraph.io/u/matthewmcneely)\
**Post date:** [July 25, 2022, 4:53pm UTC](https://discuss.dgraph.io/t/can-new-edges-be-added-to-large-numbers-of-existing-nodes-by-referencing-a-nodes-type/17566/6 "2022-07-25T16:53:14Z")

</div>

> [@nick-walt](#):
>
> Does this mean that Edges can be like a type wrapper for the Node to which it points? Where a Director Edge (from a Movie Node) points to a Person, thereby saying that that person is a type Director?

I tend to think of edges as attributes when data modeling. But I don’t think your definition is wrong, just another perspective.

One interesting aspect of GraphQL SDL in this case is the `interface` construct. In the case above, you could have a `Person` interface type, of which `Director` (and `Actor`, etc) could derive. In the `Movie` type, the `directors` edge could be defined as an array of `Person` (`directors [Person]`). This would allow you to add any `Person` as a director. However, that might not be a good idea if the `Director` derived type has attributes (edges) that are needed by the application. In that case, better to declare `directors [Director]`. dgraph GraphQL mutations will ‘type check’ supplied values in that case and enforce only `Director` types.

> [@nick-walt](#):
>
> Depending on the function that Person is either a Director or a Father? This is awesome! Is this why Neo4J mandates that all Edges are strictly typed?

If you haven’t read the GraphQL spec on interfaces and derived types: [https://graphql.org/learn/schema/#interfaces](https://graphql.org/learn/schema/#interfaces)
