DEV Community

Ivan S Glazunov for Deep.Foundation

Posted on

Associative links

What is the ideal "quantum of information" or "minimal unit of meaning" and why to ask such a question? There is a lot of pain associated with this, often not even realized. We offer a solution, but first you need to figure out what it is for. We recommend you to read the first article in a series.

Retrospective

Relational tables, document oriented databases, jsonb stores ... We often use the model in the table/collection as the minimum unit of meaning. The model consists of columns/fields with a different structure, and reflects some real object or abstract concept defined by the author.

This approach creates problems:

  • Lots of address spaces. (If you do not see it as a problem, then soon where will be an article exclusively on this topic, and you will see why this problem is real).
  • Many control points of the data structure that are expensive to change.
  • Compatibility only at the level defined by the author.
  • Failure to fully describe something new without creating another table/collection.
  • The inability to separate objects from the relationships between them.

All of these problems are addressed in the Deep.Case associative model of data.

If you are interested in optimization or search by ranges in a graph, there will be a link here to that article.

Let's dig into it

Deep.Case operates with the Link concept as a minimal unit of meaning / quantum of information.

Links table

Links (a network of links) is very similar to a graph, however, the graph has a division into nodes and edges referring only to nodes. Links do not divide these address spaces. This allows links to refer to links and carry any meaning that the author of the data models can put in them.

1

Link structure

The link structure consists of the required unique id and type_id used as the type of this link. The optional from_id and to_id fields can only be specified together.

Types for creating links are easily created by the user himself within the project model, or supplied with imported model packages.

The specified from_id and to_id fields refer to other links. Any relationship can be described with such links.

2

{
  links(where: { id: { _eq: 8 } }) {
    id
    type_id
    from_id
    to_id
  }
}
Enter fullscreen mode Exit fullscreen mode
{
  "data": {
    "links": [
      {
        "id": 8,
        "type_id": 1,
        "from_id": 7,
        "to_id": 6
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Link as a node

You can leave from_id and to_id fields empty in links. Such links play the role of a node, a point, an object of relations.

3

{
  links(where: { id: { _eq: 28 } }) {
    id
    type_id
    from_id
    to_id
  }
}
Enter fullscreen mode Exit fullscreen mode
{
  "data": {
    "links": [
      {
        "id": 28,
        "type_id": 6,
        "from_id": 0,
        "to_id": 0
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Link as a link

If from_id and to_id are specified, the link plays the role of a relationship between nodes or links. It can answer the question of how they are related using type_id. The environment of a node with links can answer many questions about its meaning, relationships, purpose, value and state.

4

{
    links(where: { id: { _in: [6,7,8] } }) {
    id
    type_id
    from_id
    to_id
  }
}
Enter fullscreen mode Exit fullscreen mode
{
  "data": {
    "links": [
      {
        "id": 6,
        "type_id": 1,
        "from_id": 0,
        "to_id": 0
      },
      {
        "id": 7,
        "type_id": 1,
        "from_id": 0,
        "to_id": 0
      },
      {
        "id": 8,
        "type_id": 1,
        "from_id": 7,
        "to_id": 6
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Unified GraphQL API

This API allows to do a lot of things, such as traversal to all children/parents in certain subtrees using index. But there will be separate articles about this.

Obviously, the structure of the link itself is available there, and also from a link you can go to other links both by its links (from_id and to_id) and by backwards references from other links (outgoing and incoming). For example, you can go to all links that refer to this link by from_id (these links go from it) using relationship out, or by to_id (these links go to it) using relationship in.

5

{
    links(where: { id: { _eq: 8 } }) {
        id
        type { id }
        from {
            id
            type_id
            from_id
            to_id
            out {
                id
                type_id
                from_id
                to_id
            }
        }
        to {
            id
            type_id
            from_id
            to_id
            in {
                id
                type_id
                from_id
                to_id
            }
        }
    }
}
Enter fullscreen mode Exit fullscreen mode
{
  "data": {
    "links": [
      {
        "id": 8,
        "type": {
          "id": 1
        },
        "from": {
          "id": 7,
          "type_id": 1,
          "from_id": 0,
          "to_id": 0,
          "out": [
            {
              "id": 8,
              "type_id": 1,
              "from_id": 7,
              "to_id": 6
            }
          ]
        },
        "to": {
          "id": 6,
          "type_id": 1,
          "from_id": 0,
          "to_id": 0,
          "in": [
            {
              "id": 8,
              "type_id": 1,
              "from_id": 7,
              "to_id": 6
            },
            {
              "id": 13,
              "type_id": 1,
              "from_id": 6,
              "to_id": 6
            },
            {
              "id": 24,
              "type_id": 22,
              "from_id": 23,
              "to_id": 6
            }
          ]
        }
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

SQL-like queries

We can receive not only the data on the structures described above. We can use the sql-like where predicate to perform a variety of complex filtering at each level.

{
  links(where: {id: { _eq: 6 } }) {
    id
    type { id }
    from { id }
    to { id }
    out(where: { from_id: { _eq: 6} }) {
      id
      type_id
      from_id
      to_id
    }
    in(where: { type_id: { _eq: 1} }, limit: 1) {
      id
      type_id
      from_id
      to_id
    }
  }
}
Enter fullscreen mode Exit fullscreen mode
{
  "data": {
    "links": [
      {
        "id": 6,
        "type": {
          "id": 1
        },
        "from": null,
        "to": null,
        "out": [
          {
            "id": 13,
            "type_id": 1,
            "from_id": 6,
            "to_id": 6
          }
        ],
        "in": [
          {
            "id": 8,
            "type_id": 1,
            "from_id": 7,
            "to_id": 6
          }
        ]
      }
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Subscriptions

And all of this already with support for subscriptions. You can simply describe to which structure you want to subscribe - and you will receive updates on the results of your query in real-time.

subscription {
  links(where: { from_id: { _eq: 7 }, to_id: { _eq: 6 } }) {
    id
    type_id
  }
}
Enter fullscreen mode Exit fullscreen mode

Support associative technologies

We create a development environment (boxed CE / EE version and SaaS version), which allows you to use data storage for solving your business problems with the ability to adapt to any business changes using an associative approach. We will create a distributed network of server clusters in a single associative space, including so as not to think about regional legislation when creating a project. We create a culture of publishing reusable data models with their behavior.
Join our community on Discord. Sign up for early access on our Waitlist or support us on Patreon.
On our site you can find links to drafts of future articles in development, links to code sources, plans for project and product management and invest presentations.

Top comments (0)