> For the complete documentation index, see [llms.txt](https://gremlify.gitbook.io/gremlify/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gremlify.gitbook.io/gremlify/schema.md).

# Define a Schema

An optional feature that allows you to define a schema for your Graph

Schemas define the structure of your Graph data, e.g what nodes and edges are valid.Generally speaking, TinkerPop, which is used by Gremlify as the Graph database engine, is schema less. But if you work, or plan to work with Graphs such as [JanusGraph](https://janusgraph.org/) or [OrientDB](https://orientdb.org/) you might find it useful (or if you are just curious about schemas!).

{% hint style="info" %}
Note: schemas are **optional**. If you are not interested in creating one, you might want to skip this article.
{% endhint %}

Let's for instance take the following simple schema as an example:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRofOvxXxYhcRQfzi3%2F-MHRrNImFMY2hwqLvyzh%2Fimage.png?alt=media\&token=42309f02-2c15-42bc-8e48-cf7b8279e789)

That basically means, that a **person** can own a **pet**, and be friends with another **person**, but any other relation is invalid.

## Create a Schema from scratch

To define a schema, click on the "Schema" tab on the side menu of the Graph Builder panel:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRofOvxXxYhcRQfzi3%2F-MHRqLPx6BTf6F74WYYZ%2Fimage.png?alt=media\&token=bb915ae8-7573-4b6f-8d36-3d68e4c9f968)

\
The Schema builder is an **interactive interface**, that requires both **mouse** and **keyboard** interactions.‌

Below is a list of all available keyboard & mouse combinations:

| Action            | Combination                           |
| ----------------- | ------------------------------------- |
| **Create Vertex** | Shift + Left Mouse click (somewhere)  |
| **Create Edge**   | Shift + Drag mouse between 2 Vertices |
| **Delete Vertex** | Select Vertex + Backspace             |
| **Delete Edge**   | Select Edge + Backspace               |
|                   |                                       |

Let's create the schema from above. We'll start by creating the **person** node (hit **shift + mouse).**

The following dialog will open up:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRofOvxXxYhcRQfzi3%2F-MHRsbDSw2t607NvEx0L%2Fimage.png?alt=media\&token=d6c7a20a-2eb3-450e-89d8-1269427fdae8)

Let's fill it up with the following properties, and then hit **save**:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRofOvxXxYhcRQfzi3%2F-MHRskAa1r3XoAzHyQHY%2Fimage.png?alt=media\&token=a338341b-59fc-42cc-a39e-d9cbfef8ccf6)

{% hint style="info" %}
Note: currently three types of data are supported: **string,** **boolean** and **number**
{% endhint %}

We can now repeat the same process with the **pet** node, but with a slight difference of the properties:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRofOvxXxYhcRQfzi3%2F-MHRtF3_-XDpbsBZS0KC%2Fimage.png?alt=media\&token=fc0a541f-5853-4a2d-bf04-d83b7a6176f5)

Our schema should look as follows:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRtHVV8qLIraST3687%2F-MHRtf2rKN3M_EbIYt7I%2Fimage.png?alt=media\&token=067214ea-f340-4f2d-b245-f150deb576df)

Now let's create the **owns** relationship by holding **shift** and dragging the mouse into **pet**. Similarly to the node creation, a dialog will open. The results:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRtHVV8qLIraST3687%2F-MHRtqlIX_HWZP9o5iOU%2Fimage.png?alt=media\&token=2d2c672e-2ffd-4192-9b47-f23c126ffd2c)

Now, to create the **friendOf** relation, we'll hold **shift** and drag the moue from **person** to itself:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRtHVV8qLIraST3687%2F-MHRuZFhe3eA1TUWLTfy%2Fimage.png?alt=media\&token=f02e3996-620b-4c96-9ebd-2ddce9538341)

Our schema is ready for work! let's try it out by moving to the **Graph** tab, and create a node. The following dialog opens:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV0i--vX9zqGzdAWF-%2Fimage.png?alt=media\&token=681fcd00-19c7-4e51-908e-e272afdeedd2)

As you can see, any property we defined in our schema is labeled with it's corresponding type. That implies that trying to fill it with invalid values will throw an error:

&#x20;

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV1PLc3JpHZ7sNkaSc%2Fimage.png?alt=media\&token=7676b796-dcb7-44a3-9660-f63817dbf8d6)

In addition, and in contrary to the schema-less Graph,  you can only create nodes and edges with the labels defined in the schema. Use the label dropdown for that matter.

Let's create a few nodes:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV2B-Uk4eM2NpRvfsc%2Fimage.png?alt=media\&token=e283d840-90de-419a-b57f-32ac6e3c5bb3)

Our graph is not complete without some relationships. Assuming that node #18 owns pet #13, and nodes #18 and #22 are friends. Our graph will look like this:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV2qgvpjf19pB9L3-1%2Fimage.png?alt=media\&token=46d6c94c-a2f1-415f-b8b4-4ac8f457e827)

But what happens if we try to connect the **pet** node with a **person** node with the **owns** relationship? (hopefully, this kind of scenario will not happen in the future!):

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV37iFumJTTdazOwvI%2Fimage.png?alt=media\&token=4b9b6020-57f4-4877-a921-0a2249a5b390)

It fails.

But what if we tried to do that via the query editor?

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV3yYTahTmq6o7f23J%2Fimage.png?alt=media\&token=0905cf67-7caa-46a8-9c4d-3f56da110572)

The query will fail.

## Create a Schema from an existing Graph

Assuming you already have a Gremlify Graph working, and you wish to attach a Schema to it:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV552tg2zfUS4aNFWc%2Fimage.png?alt=media\&token=ce1788d4-d090-4e4b-a518-ad5db1e9b285)

When we click on the **Schema** tab, a dialog pops up:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV4fr7qzpVWRVZXJq_%2Fimage.png?alt=media\&token=e1ce3939-ee9c-4ad0-b66e-6defb7fc351c)

By clicking yes, gremlify will take any node and edge in your graph, and create a schema out of them:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV6jfQharGTu-lTml5%2Fimage.png?alt=media\&token=97ce515a-b69b-4980-8c74-7b84e95ed75a)

### What about the properties?

For any two given labeled entities, the algorithm will make a **union** of their properties. Ambiguous types will be handled arbitrarily.

For example, two **person** nodes (we'll call them X and Y) with the following properties:

| property  | X      | Y      |
| --------- | ------ | ------ |
| label     | person | person |
| name      | john   | emma   |
| age       | 26     | 34     |
| isMarried | true   | -      |

The resulting schema node will be:

| property  | type/value |
| --------- | ---------- |
| label     | person     |
| name      | string     |
| age       | number     |
| isMarried | boolean    |

## Altering a Schema

When altering an existing Schema, two main scenarios might take place:

#### The Schema is still synced with our Graph:

That means that the change has no actual effect on our existing graph. Nothing special happens in this scenario.

#### The Schema is now out of sync with our Graph:

Let's take a look at the following Schema from the previous example:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV9dFbxyQRkbOBG-gr%2Fimage.png?alt=media\&token=a2ac5abf-58c7-4980-ad44-27b93e28f977)

Now if we decide to remove the **knows** edge from our schema. Immediately a dialog opens up

:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHV9sx9uW8DKP_Xdm0F%2Fimage.png?alt=media\&token=2265175e-0c3e-4a3c-bb9a-5b7a272de6c1)

TL;DR. our Graph contains at least one edge with the **knows** label. If we hit **yes**, Gremlify will remove any edge in the Graph that is labeled with **knows**, and the resulting Graph will look as follows:

![](https://474726345-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M56c-7vpzHzvI18WCVd%2F-MHRua9o-vHQBIp1MwkM%2F-MHVAHpzsrjEqYOtgNbd%2Fimage.png?alt=media\&token=3e76de65-7218-49fa-892f-36b4899ed90a)

The same goes for any node or property, including a scenario where a property type changes.
