Search code examples
hyperledgerhyperledger-composer

Querying over nested assets in Hyperledger Composer


I want to write a specific query for my Hyperledger Composer app. Below, I have 2 assets and a transaction. Asset1 has a field called contents, which is an array of type Asset2. The associated code is below:

namespace org.acme.biznet

asset Asset1 identified by Asset1Id {
    o String Asset1Id
    --> Asset2[] contents
}

asset Asset2 identified by Asset2Id {
    o String Asset2Id
}

transaction Transact {
    --> Asset1 asset1
}

I want to select all instances of Transact where the associated Asset1 has a specified Asset2 inside. The closest solution I came to the query below, which did not work.

query GetTransactionsThatHaveAsset2 {
    description: ""
    statement: 
        SELECT org.acme.biznet.Transact
            WHERE (asset1.contents CONTAINS (Asset2Id == _$propId))
}

The thing is, I have also written the query below.

query GetAsset1sThatHaveAsset2 {
    description: ""
    statement: 
        SELECT org.acme.biznet.Asset1 
            WHERE (contents CONTAINS (Asset2Id == _$propId))
}

This query behaves as intended, but it's selecting over Asset1. I want to select over Transact. How would I write this query?


Solution

  • no, you can't presently nest the query like you propose, nested named queries are not currently implemented in Composer (CouchDB is not a relational DB, and hence Composer query language can't translate the nested query presently to be translated to CouchDB) 2) Transact is a transaction - it contains a relationship identifier(s) you defined in your model, not the nested data stored in the related asset. You would have to define a query that searches for all transactions that matches the asset1 identifier field you passed to the trxn - then in your code, you can check transact.asset1.contents contains the 'something' (passed in to the trxn too?) using a javascript match - quite straightforward). Alternatively, you could use the REST API filters (loopback filters as opposed to queries) where (form your app code) you can resolve the relationships of transaction (Transact) back to asset1 (and its contents) using the REST call with filter eg {"where":{"asset1":"resource:org.acme.net.Asset1#1"}, "include":"resolve"} . Hope this helps, maybe its nesting you're looking for exclusively..