How do I expand all non-uid predicates, plus some specific edges?

What I want to do

I would like to get all the non-uid predicates, and expand some specific edges. Say, for example, that on the example data from the docs I would like to get all the data about directors named Steve, as well as a list of their respective films. This seems to be a similar problem as this Github issue, but the solution outlined there doesn’t quite do what I need.

What I did

The thing I tried first was

{
  me(func: allofterms(name@en, "Steven")) {
    expand(_all_)
    director.film  {
      expand(_all_)
    }
  }
}

However, this returns the error Repeated subgraph: [director.film] while using expand(). The Github issue mentioned above suggests this as an alternative (slightly adapted for the example):

{
  steven as var(func: allofterms(name@en, "Steven"))
  directors(func: uid(steven)) {
    expand(_all_)
  }
  films(func: uid(steven)) {
    director.film  {
      expand(_all_)
    }
  }
}

However, what I don’t understand about this solution is how to match the director to the film, since this query returns the two requested things in separate entries. This is not addressed in the Github issue.

Dgraph metadata

dgraph version

Dgraph version : v21.03.0
Dgraph codename : rocket
Dgraph SHA-256 : b4e4c77011e2938e9da197395dbce91d0c6ebb83d383b190f5b70201836a773f
Commit SHA-1 : a77bbe8ae
Commit timestamp : 2021-04-07 21:36:38 +0530
Branch : HEAD
Go version : go1.16.2
jemalloc enabled : true

If you have a well defined Schema, you can do this

{
  me(func: allofterms(name@en, "Steven")) {
    expand(_all_) {
      expand(_all_)
    }
  }
}

The problem with that is that it follows all the edges. In my case that would return much more data than I want, and would require me filtering the output afterwards.

1 Like

I think the problem with the request is that everything is the same kind of edge to the query. You want all “predicates” (string|int|float|etc.) plus a few specific “edges” (uid) but DQL doesn’t know what predicates (S.P.O. context) are “predicates” and which ones are “edges”.

This is confusing to say because edge and predicate are often used interchangeably by Dgraph.

If you wanna return just predicates/values/data you could create a fake type and use like that

expand(myFakeType)

This can be used in other situations too.

but the myFakeType would have to be pre-defined in the DQL schema correct? Would the node have to have this type or because you explicitly expand with it, it does not check that the node has the type and it just looks for the fields.

It need to be created in the Schema. After that you can use it anywhere with expand()

1 Like

Oh, that is interesting, good to know! Thanks @amaster507 and @MichelDiz for the input. Sadly it still doesn’t quite solve my specific problem completely. This is because in my case I don’t know necessarily what type the first node has and, therefore, which fields it has. Therefore I really want to use expand(all) for the non-uid fields. For now I went with the expand(all) { expand(all) } and filter manually approach.

No problem, create a fake type with all possible predicates and edges. The one that doesn’t exist will be ignored.