# How do I express a many-to-many relation in a TypeQL schema?

**URL:** <https://forum.typedb.com/t/how-do-i-express-a-many-to-many-relation-in-a-typeql-schema/73>\
**Category:** TypeQL\
**Tags:** schema-design\
**Created:** [21 March 2022 11:15 UTC](https://forum.typedb.com/t/how-do-i-express-a-many-to-many-relation-in-a-typeql-schema/73 "2022-03-21T11:15:35Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![alex](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.typedb.com/alex/32/148_2.png) [@alex](https://forum.typedb.com/u/alex)\
**Post date:** [21 March 2022 11:15 UTC](https://forum.typedb.com/t/how-do-i-express-a-many-to-many-relation-in-a-typeql-schema/73/1 "2022-03-21T11:15:35Z")

</div>

Given a set of Authors and a set of Publications, I want to model an N…N (many-to-many) relationship between Authors and Publications, such that one publication may have many authors, and one author may have many publications.

How would I do that in TypeQL?

---

<div class="post-metadata">

**Author:** ![alex](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.typedb.com/alex/32/148_2.png) [@alex](https://forum.typedb.com/u/alex)\
**Post date:** [21 March 2022 11:23 UTC](https://forum.typedb.com/t/how-do-i-express-a-many-to-many-relation-in-a-typeql-schema/73/2 "2022-03-21T11:23:51Z")

</div>

In TypeQL, relations are first-class citizens. In this way it differs from languages such as SQL where relations are expressed via foreign keys and join tables.

TypeQL relations are many-to-many by default, which means that we need only write:

```nohighlight
define
person sub entity, owns name;
publication sub entity, owns name;
name sub attribute, value string;
authorship sub relation, relates author, relates authored;

```

allowing us to insert entities

```nohighlight
insert
$king isa person, has name "Stephen King";
$straub isa person, has name "Peter Straub";
$talisman isa publication, has name "The Talisman";

```

Now there are actually two options for the relation model: either we create a separate relation for each person-publication link, or we use one N-ary relation per publication. The first approach yields

```nohighlight
(author: $king, authored: $talisman) isa authorship;
(author: $straub, authored: $talisman) isa authorship;

```

while the second approach gives

```nohighlight
(author: $king, author: $straub, authored: $talisman) isa authorship;

```

In this particular instance I would actually adopt the second approach. This is because it feels quite “natural”; when you look at a book, you’ll see _all_ of its authors listed on the cover, and there are other meaningful attributes we can attach to an authorship - for instance we could add

```nohighlight
define
publication-date sub attribute, value datetime;
authorship owns publication-date;

```

allowing us to insert the relation

```nohighlight
(author: $king, author: $straub, authored: $talisman) isa authorship, has publication-date "1984-11-08";

```

---

<div class="post-metadata">

**Author:** ![even](https://avatars.discourse-cdn.com/v4/letter/e/7993a0/32.png) [@even](https://forum.typedb.com/u/even)\
**Post date:** [3 May 2022 01:48 UTC](https://forum.typedb.com/t/how-do-i-express-a-many-to-many-relation-in-a-typeql-schema/73/3 "2022-05-03T01:48:54Z")

</div>

authorship is a N-N relation ,also called hyperedge or hyperrelation  
how to query the entity of authorship,and the data of authorship?

---

<div class="post-metadata">

**Author:** ![alex](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.typedb.com/alex/32/148_2.png) [@alex](https://forum.typedb.com/u/alex)\
**Post date:** [3 May 2022 09:12 UTC](https://forum.typedb.com/t/how-do-i-express-a-many-to-many-relation-in-a-typeql-schema/73/4 "2022-05-03T09:12:34Z")

</div>

Depends on exactly what you’re looking for - some examples of `match` queries over authorships:

Retrieve all (author, authored) pairs:

```nohighlight
match
(author: $author, authored: $authored) isa authorship;

```

Retrieve all (author, authored) pairs including publication date:

```nohighlight
match
$r (author: $author, authored: $authored) isa authorship, has publication-date $pubdate;

```

Retrieve all publications co-authored by King and Straub:

```nohighlight
match
$king isa person, has name "Stephen King";
$straub isa person, has name "Peter Straub";
(author: $king, author: $straub, authored: $authored) isa authorship;

```

---

<div class="post-metadata">

**Author:** ![Newone](https://avatars.discourse-cdn.com/v4/letter/n/da6949/32.png) [@Newone](https://forum.typedb.com/u/Newone)\
**Post date:** [11 August 2023 07:16 UTC](https://forum.typedb.com/t/how-do-i-express-a-many-to-many-relation-in-a-typeql-schema/73/5 "2023-08-11T07:16:22Z")

</div>

On a similar note, how do I define a rule that detects a many to many relationship?

---

<div class="post-metadata">

**Author:** ![jameswhiteside](https://dub1.discourse-cdn.com/flex005/user_avatar/forum.typedb.com/jameswhiteside/32/94_2.png) [@jameswhiteside](https://forum.typedb.com/u/jameswhiteside)\
**Post date:** [11 August 2023 11:24 UTC](https://forum.typedb.com/t/how-do-i-express-a-many-to-many-relation-in-a-typeql-schema/73/6 "2023-08-11T11:24:47Z")

</div>

Hi, could you please provide a specific example of the kind of data patttern you want to detect? If you want to detect relations that have more than one roleplayers for multiple roles, you could do something like:

```auto
rule label-many-to-many:
  when {
    $a isa thing;
    $b isa thing;
    not { $a is $b; };
    $c isa thing;
    $d isa thing;
    not { $c is $d; };
    my-relation relates $rol1;
    my-relation relates $rol2;
    not { $rol1 is $rol2; };
    $rel ($rol1: $a, $rol1: $b, $rol2: $c, $rol2: $d) isa my-relation;
  } then {
    $rel has is-many-to-many true;
  };

```

You’d also need to allow `my-relation` to own `is-many-to-many` for this to work, and in general it’s pretty difficult to know if this will work without a specific example to test it on, so you may need to tweak this rule significantly to meet your use case.

---

<div class="post-metadata">

**Author:** ![Newone](https://avatars.discourse-cdn.com/v4/letter/n/da6949/32.png) [@Newone](https://forum.typedb.com/u/Newone)\
**Post date:** [11 August 2023 23:43 UTC](https://forum.typedb.com/t/how-do-i-express-a-many-to-many-relation-in-a-typeql-schema/73/7 "2023-08-11T23:43:37Z")

</div>

What I am trying to do is make a system that learns. I wrote about it in topic:

> [@Schemas and propositional logic rules](https://forum.typedb.com/t/schemas-and-propositional-logic-rules/380/6):
>
> What I would like to do is a system that learns through inference and by providing a small set of general rules, the system sould be able to create new rules for itself. Now as I understand it, Typedb cannot create new rules for itself without having an external application to incert said rules. That is where an application like Rasa comes in. Rasa has custom actions. Typedb could infer through propositional logic what new rules does it need to learn something new and send that information t…
