How can I filter a type that holds a specific predicate uid?

How can I filter a type that holds a specific predicate uid?
Example schema:

type Product {
	id: ID!
    brand(filter: BrandFilter): Brand! @hasInverse(field: products)
}


type Brand {
    id: ID!
    name: String! @id @search
    products: ...
}

....

So can I get a Product that has a Brand with uid=“0x12345”?

Obviously filtering the brand like below doesn’t work because it returns all Products instead and one of them contains the brand with the 0x12345 uid as well. Instead, I need to get the whole Product that has that brand.

{
query(func: type(Product)){
  uid
  Product.brand @filter(uid("0x12345")){
    uid
    expand(_all_)
  }
}
}

Dgraph metadata

dgraph version

v21.12.0

If you have the UID you can just query for it. This is not SQL, you do not need to start with the table/type and filter it further. Instead just start with what you actually want.

{
    query(func: uid(0x1234)){
        uid
        expand(_all_)
    }
}

If you want to make sure that the uid is part of a type definition, you can filter for it:

{
    query(func: uid(0x1234))@filter(type(some_type)){
        uid
        expand(_all_)
    }
}
1 Like

@vnium Thanks for the response. Let me add more context. I don’t have the Product ID. I have only the Brand uid. I need to get the Product that holds the Brand with uid 0x1234. I tried everything that is in the Dgraph documentation. It seems that there is no way to do it with filters. I wonder if I need to do multiple queries here with upsert.

Try the query below. This will start with Brand node 0x12345 and expand to all associated products.

{
    query(func: uid("0x12345")){
        Brand.products{
            uid
            expand(_all_)
        }
    }
}

Thanks @vnium

Is there any way to get multiple uids for Brands based on another query and add them as filters?

Yes, check “Query Variables” and “Value Variables” in the DQL docs. You can try something like below:

{

    var(func: <some_query_to_get_brands>){
        variableWhichHoldsAllSelectedBrands as uid
    }
    
    q(func: uid(variableWhichHoldsAllSelectedBrands)){
        Brand.products{
            uid
            expand(_all_)
        }
    }
}

This would return all products of all selected brands.

1 Like

If you have a list of uids and you want to filter a list on entities having a relation (a predicate) to those uid, consider using uid_in function in a filter :
https://dgraph.io/docs/query-language/functions/#uid_in

function uid_in allows looking ahead along an edge to check that it leads to a particular UID.

2 Likes