@hasInverse does not work with RDF input

I want a 2 way edge between Genre and Work. After feeding in a set of Works with their respective genres, I want to query all works for a given genre. Here’s my schema:

type Genre {
    genreName: String! @id
    genreType: String!
    works: [Work] @hasInverse(field: genre)
}

type Work {
    workId: String! @id
    title: String!
    genre: Genre
}

This works with GraphQL mutation input, but not with RDF input pushed from Slash:

{
  set{
    _:Work.1 <Work.workId> "1" .
    _:Work.1 <Work.title> "Hamlet" .
    _:Work.1 <dgraph.type> "Work" .
    _:Genre.1 <Genre.genreName> "t" .
    _:Genre.1 <Genre.genreType> "Tragedy" .
    _:Genre.1 <dgraph.type> "Genre" .
    _:Work.1 <Work.genre> _:Genre.1 .
  }
}

With this input, I can find a work’s genre.
image

But querying for works under a genre returns an empty set.
No works returned for tragedy

What can be done here? Feeding data with GraphQL mutations or putting reverse edges manually would be difficult, for I have a 42 KLOC dataset.

It looks like we need to set uids from both sides of the relationship for the rdf based mutation to work. I tried this:

{
  set{
    _:Work.1 <Work.workId> "2" .
    _:Work.1 <Work.title> "MOV" .
    _:Work.1 <dgraph.type> "Work" .
    _:Genre.1 <Genre.genreName> "c" .
    _:Genre.1 <Genre.genreType> "Comedy" .
    _:Genre.1 <dgraph.type> "Genre" .
    _:Work.1 <Work.genre> _:Genre.1 .
# added the following link
    _:Genre.1 <Genre.works> _:Work.1 .
  }
}

The query works now.

  queryGenre(first: 10) {
    genreName
    genreType
    works {
      title
    }
  }

The result is:

  "queryGenre": [
      {
        "genreName": "t",
        "genreType": "Tragedy",
        "works": []
      },
      {
        "genreName": "c",
        "genreType": "Comedy",
        "works": [
          {
            "title": "MOV"
          }
        ]
      }
    ]

@anand does DGraph provide a way to automate this? I have a large RDF dump, adding connections manually is not feasible.

I tried adding @reverse to the DQL schema from Ratel but it didn’t work as expected. For reference: What does adding reverse edges really mean? (@reverse)

<Genre.genreName>: string @index(hash) @upsert .
<Genre.genreType>: string .
<Genre.works>: [uid] @reverse .
<Work.genre>: uid .
<Work.title>: string .
<Work.workId>: string @index(hash) @upsert .
<dgraph.cors>: [string] @index(exact) @upsert .
<dgraph.graphql.schema>: string .
<dgraph.graphql.xid>: string @index(exact) @upsert .
type <Genre> {
	Genre.genreName
	Genre.genreType
	Genre.works
}
type <Work> {
	Work.workId
	Work.title
	Work.genre
}
type <dgraph.graphql> {
	dgraph.graphql.schema
	dgraph.graphql.xid
}

AFAIK, there is no way to automate this.

I’ll try automating it with a Python script. Got a feature request for the SQL migration tool- provide an option to generate reverse edges for foreign keys.

2 Likes

Solved using regular expression. Check out this post: SQL migration tool: shenanigans and solutions

Suppose the generated dataset has Paragraph.character predicates and we want to add the inverse Character.paragraphs predicates.

In VS Code regex search for (.*?) <Paragraph.character> (.*?) . and replace with

$1 <Paragraph.character> $2 .
$2 <Character.paragraphs> $1 .

This gives us

_:Paragraph.866084 <Paragraph.character> _:Character.hamlet .
_:Character.hamlet <Character.paragraphs> _:Paragraph.866084 .

This would be nice to have rather than having to specify each link.