fabric 1.3新特性之使用分页查询CouchDB状态数据库

当CouchDB查询返回大型结果集时,可以使用一系列API,这些API可以通过调用链代码来对结果列表进行分页。 分页提供了一种机制,通过指定页面大小和起始点来划分结果集——一个指示结果集开始位置的书签。 客户端应用程序迭代地调用执行查询的链代码,直到不再返回结果。
我们将使用Marbles示例函数queryMarblesWithPagination来演示如何在链代码和客户端应用程序中实现分页。
https://github.com/hyperledger/fabric-samples/blob/master/chaincode/marbles02/go/marbles_chaincode.go
queryMarblesWithPagination –具有分页的临时丰富查询的示例。 这是一个查询,其中(选择器)字符串可以传递到类似于上面示例的函数中。 在这种情况下,查询还包括pageSize以及书签。
为了展示分页,需要更多数据。 此示例假定您已从上方添加了marble1。 在对等容器中运行以下命令以创建“tom”拥有的四个大理石,以创建由“tom”拥有的总共五个大理石:

peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble2","yellow","35","tom"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble3","green","20","tom"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble4","purple","20","tom"]}'
peer chaincode invoke -o orderer.example.com:7050 --tls --cafile /opt/gopath/src/github.com/hyperledger/fabric/peer/crypto/ordererOrganizations/example.com/orderers/orderer.example.com/msp/tlscacerts/tlsca.example.com-cert.pem -C $CHANNEL_NAME -n marbles -c '{"Args":["initMarble","marble5","blue","40","tom"]}'

除了前一个示例中的查询参数之外,queryMarblesWithPagination还添加了pagesize和bookmark。 PageSize指定每个查询返回的记录数。 书签是一个“锚”告诉couchDB从哪里开始页面。 (每个结果页面都会返回一个唯一的书签。)
queryMarblesWithPagination是Marbles链码中函数的名称。 注意垫片shim.ChaincodeStubInterface用于访问和修改分类帐。 getQueryResultForQueryStringWithPagination()将queryString以及pagesize和bookmark传递给shim API GetQueryResultWithPagination()。
 

func (t *SimpleChaincode) queryMarblesWithPagination(stub shim.ChaincodeStubInterface, args []string) pb.Response {

      //   0
      // "queryString"
      if len(args) < 3 {
              return shim.Error("Incorrect number of arguments. Expecting 3")
      }

      queryString := args[0]
      //return type of ParseInt is int64
      pageSize, err := strconv.ParseInt(args[1], 10, 32)
      if err != nil {
              return shim.Error(err.Error())
      }
      bookmark := args[2]

      queryResults, err := getQueryResultForQueryStringWithPagination(stub, queryString, int32(pageSize), bookmark)
      if err != nil {
              return shim.Error(err.Error())
      }
      return shim.Success(queryResults)
}


以下示例是一个peer命令,它调用queryMarblesWithPagination,pageSize为3且未指定书签。
注意⚠️:如果未指定书签,则查询以“第一”记录页开头。
```

// Rich Query with index name explicitly specified and a page size of 3:
peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["queryMarblesWithPagination", "{\"selector\":{\"docType\":\"marble\",\"owner\":\"tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}","3",""]}'


```
收到以下响应(为清晰起见添加了回车),因为pagsize设置为3,所以返回五个大理石中的三个:
```

[{"Key":"marble1", "Record":{"color":"blue","docType":"marble","name":"marble1","owner":"tom","size":35}},
 {"Key":"marble2", "Record":{"color":"yellow","docType":"marble","name":"marble2","owner":"tom","size":35}},
 {"Key":"marble3", "Record":{"color":"green","docType":"marble","name":"marble3","owner":"tom","size":20}}]
[{"ResponseMetadata":{"RecordsCount":"3",
"Bookmark":"g1AAAABLeJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYqz5yYWJeWkGoOkOWDSOSANIFk2iCyIyVySn5uVBQAGEhRz"}}]



⚠️:书签由CouchDB为每个查询唯一生成,并表示结果集中的占位符。 在后续的查询迭代中传递返回的书签以检索下一组结果。
以下是使用pageSize为3调用queryMarblesWithPagination的peer命令。请注意,这次查询包含从上一个查询返回的书签。
 

peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["queryMarblesWithPagination", "{\"selector\":{\"docType\":\"marble\",\"owner\":\"tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}","3","g1AAAABLeJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYqz5yYWJeWkGoOkOWDSOSANIFk2iCyIyVySn5uVBQAGEhRz"]}'



收到以下响应(为清楚起见,添加了回车)。 检索最后两条记录:

 

[{"Key":"marble4", "Record":{"color":"purple","docType":"marble","name":"marble4","owner":"tom","size":20}},
 {"Key":"marble5", "Record":{"color":"blue","docType":"marble","name":"marble5","owner":"tom","size":40}}]
[{"ResponseMetadata":{"RecordsCount":"2",
"Bookmark":"g1AAAABLeJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYqz5yYWJeWkmoKkOWDSOSANIFk2iCyIyVySn5uVBQAGYhR1"}}]


最后一个命令是一个peer命令,用于调用queryMarblesWithPagination,其pageSize为3,并带有上一个查询的书签。
 

peer chaincode query -C $CHANNEL_NAME -n marbles -c '{"Args":["queryMarblesWithPagination", "{\"selector\":{\"docType\":\"marble\",\"owner\":\"tom\"}, \"use_index\":[\"_design/indexOwnerDoc\", \"indexOwner\"]}","3","g1AAAABLeJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYqz5yYWJeWkmoKkOWDSOSANIFk2iCyIyVySn5uVBQAGYhR1"]}'


收到以下响应(为清楚起见,添加了回车)。 没有返回任何记录,表明已检索到所有页面:

 

[]
[{"ResponseMetadata":{"RecordsCount":"0",
"Bookmark":"g1AAAABLeJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYqz5yYWJeWkmoKkOWDSOSANIFk2iCyIyVySn5uVBQAGYhR1"}}]


有关客户端应用程序如何使用分页迭代结果集的示例,请在Marbles示例中搜索getQueryResultForQueryStringWithPagination函数。
https://github.com/hyperledger/fabric-samples/blob/master/chaincode/marbles02/go/marbles_chaincode.go

你可能感兴趣的:(hyperledger,fabric)