Pagination on child object that belongs to various parent object types

I have a schema that at a high level looks like this

<Restaurant.name>: string @index(fulltext, trigram) .
<Restaurant.address>: uid @reverse .
<Boutique.name>: string @index(fulltext, trigram) .
<Boutique.address>: uid @reverse . 
<Address.address1>: string @index(fulltext, trigram) .
<Address.city>: uid @reverse .
<City.name>: string @index(fulltext, trigram) .
<City.state>: uid @reverse .
<State.name>: string @index(fulltext, trigram) .

And I want to do a reverse lookup with pagination of all restaurants within a given city, so I worked out something like this to begin with.

query {
    Restaurants (func: anyoftext(State.name, "new york")) @cascade {
        State.name
        ~City.state {
            City.name
            ~Address.city (first:10, offset:10)  {
                Address.address1
                ~Restaurant.address {
                    Restaurant.name 
                }
            }
        }
    }
}

So I’m trying to get all Addresses in the state of New York (or any state(s) really), and limiting the type of store to only Restaurants. But when I run this query, it retrieves less than 10 Restaurants when I know there’s more than that.

What I’ve found was since the address can have different parent types, all the Addresses that belong to Boutiques were “hidden” but still included in the pagination search, meaning when I ask for 10 results I will always potentially get less, which isn’t very deterministic.

So I feel like I’m probably doing something wrong here, is there a better way to write this query to get what I’m looking for? Or are things done wrong starting from the schema itself?

EDIT: My db version is v20.11.2-rc1-25-g4400610b2, and I’m using Cascade to limit the type to Restaurants

You will probably want to include what version of the database you are using - the execution of @cascade and pagination was flipped in v21.03+ from what it was in v20.11-. Meaning in v20.11 pagination was done before removing results that do not include all cascaded fields - while in v21.03+, all pagination is applied after the graph is built and trimmed via @cascade. So, the v20.11 version of that logic could very well cause what you are seeing, as the first 10 results may not have all the required fields and subsequently be trimmed.

But, assuming you are on v21.03.x, you may want to include a minimal RDF example of your data that reproduces the issue so someone can easily reproduce on their own to provide a better answer.

1 Like

You’re exactly right, I’m on 20.11 (I’ve included that in an edit) and that’s what I’m seeing without realizing that it was the problem. I included the cascade originally because I assumed it would follow the 21.03.x logic that would trim via cascade first before pagination. I’ll look into updating the db version that would solve this problem.

Though would there be a way to do this in 20.11 as well if it’s not easy to update the db version? Or would it be more complex?

more complex, yes - but not by much. Basically save your results without pagination in a query variable, then use the query variables in another query without cascade.

eg: (didnt run this btw)


query {
    l0 as var(func: anyoftext(State.name, "new york")) @cascade {
        l1 as ~City.state {
            l2 as ~Address.city {
                l3 as ~Restaurant.address 
            }
        }
    }
  Restaurants (func: uid(l0)) {
    State.name
    ~City.state @filter(uid(l1)) {
      City.name
      ~Address.city @filter(uid(l2)) (first:10, offset:10)  {
        Address.address1
        ~Restaurant.address @filter(uid(l3)) {
           Restaurant.name 
        }
      }
    }
  }
}

(or something like that)