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

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?

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:

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

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

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

while the second approach gives

(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

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

allowing us to insert the relation

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

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

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

Retrieve all (author, authored) pairs:

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

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

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

Retrieve all publications co-authored by King and Straub:

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