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!]
}

enum TRANSACTION_TYPE {...}

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) {
      uid
      sellingPrice as Seller.sellingPrice
      sellingPriceWithTax as math(1.1 * sellingPrice)
      buyers as Seller.customers {
        uid
      }
    }
  }
  mutation {
    set {
      uid(buyers) <ITransactor.outgoingTransactions> _:transac .
      uid(sellers) <ITransactor.incomingTransactions> _:transac .
      _:transac <Transaction.from> uid(buyers) .
      _:transac <Transaction.to> 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

PASTE THE RESULTS OF dgraph version HERE.

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