Creating multiple distinct documents in DQL using blank nodes

What I want to do

I want to create multiple new documents between two sets of UIDs using blank nodes in DQL.

What I did

Given the following example schema:

interface ITransactor {
    id: ID!
    incomingTransactions: [Transaction!] @hasInverse(field: to)
    outgoingTransactions: [Transaction!] @hasInverse(field: from)
    balance: Float @lambda

type Buyer implements ITransactor {
    id: ID!

type Seller implements ITransactor {
    id: ID!
    sellingPrice: Float!
    buyers: [Buyer!]


type Transaction {
    id: ID!
    from: ITransactor
    to: ITransactor!
    amount: Float! @search
    type: TRANSACTION_TYPE! @search

I tried to do an upsert in DQL similar to the following:

upsert {
  query {
    sellers as q(func: some_func) {
      sellingPrice as Seller.sellingPrice
      sellingPriceWithTax as math(1.1 * sellingPrice)
      buyers as Seller.customers {
  mutation {
    set {
      uid(buyers) <ITransactor.outgoingTransactions> _:transac .
      uid(sellers) <ITransactor.incomingTransactions> _:transac .
      _:transac <Transaction.from> uid(buyers) .
      _:transac <> uid(sellers) .
      _:transac <dgraph.type> "Transaction" .
      _:transac <Transaction.type> "TYPE_ENUM" .
      _:transac <Transaction.amount> val(sellingPriceWithTax) .

Where sellers is a set of sellers {s1, s2, s3…} and buyers is a set of customers for each seller {s1: {b1, b3, b4…}, s2: {b2, b3, b5…}, …}. What I want is for _transac to be a set of transactions {t1, t2, t3…} between each seller and each buyer { t1: (s1, b1), t2: (s1, b3)… t4: (s2, b2)…}.

I am having two issues with this. This mutation only creates one uid for the _:transac blank node, whereas I want one for each seller-buyer combo. Also, the Transaction.amount field is not being set, possibly because it is bound to the set of sellers and therefore cannot be attributed to the _:transac node?

I would like to know if I am approaching this in the correct manner. And if not, can someone advise how I would achieve something like this in Dgraph because I can’t think of any other way to do it in GraphQL or DQL.

Dgraph metadata

dgraph version


This is the correct semantics for it. Treat a blank node as a variable for a UID. If you want a UID for each buyer-seller combo then you need to generate a blank node for each combo.

Thanks for the reply. So I guess I would have to write a mutation for each individual transaction then? I don’t see a way in DQL to iterate over a set of UIDs within a mutation

In general, this won’t work. It depends on the case. I recommend that you have two blocks. One to collect the e sellingPrice in a variable and the other the final block. Variables from the same block can happen to be null due the execution of the nested blocks.

1 Like