fabric学习(9)——使用CouchDB及索引的操作

在byfn中启用couchDB很简单

./byfn.sh up -c mychannel -s couchdb

其中的过程了解一下:

1,加上-s couchdb参数以后,byfn脚本内的启动命令就变成了

docker-compose -f docker-compose-cli.yaml -f docker-compose-couch.yaml up -d

代表着docker-compose启动的时候,把docker-compose-couch.yaml也加载进去

2,docker-compose-couch.yaml中的配置,是给4个peer各启动一个couchdb的容器,因此脚本执行完之后应该有13个容器在运行,包含1个cli,1个order,3个chaincode,4个peer,4个couchdb

3,如果在不使用docker启动的情况下,修改peer节点的core.yaml文件中的ledger.state.stateDatabase属性,并配置好couchDBAddress以及用户名和密码(默认的用户名和密码都是空的)

下面部署新的链码,并建立索引:

使用的是fabric-samples\chaincode\marbles02\go目录下的链码,该链码存储的marble的数据结构是

type marble struct {
         ObjectType string `json:"docType"` //docType is used to distinguish the various types of objects in state database
         Name       string `json:"name"`    //the field tags are needed to keep case from bouncing around
         Color      string `json:"color"`
         Size       int    `json:"size"`
         Owner      string `json:"owner"`
}

为其中的docTypeowner字段新建一个名为indexOwner的索引的配置文件indexOwner.json如下

{"index":{"fields":["docType","owner"]},"ddoc":"indexOwnerDoc", "name":"indexOwner","type":"json"}

这个json文件必须保存在链码同级别目录下的META-INF\statedb\couchdb\indexes文件夹下,目录结构如图

因此,新建索引是无需对chaincode做额外开发的,只需要在部署的时候,将对应的索引配置文件放到对应的位置即可

进入cli容器

docker exec -it cli bash

部署链码:

peer chaincode install -n marbles -v 1.0 -p github.com/chaincode/marbles02/go

实力化

export CHANNEL_NAME=mychannel
peer chaincode instantiate -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 -v 1.0 -c '{"Args":["init"]}' -P "OR ('Org0MSP.peer','Org1MSP.peer')"

打开一个新的终端窗口,然后运行下边的命令来验证索引是否被正确创建

docker logs peer0.org1.example.com  2>&1 | grep "CouchDB index"

输出

 CreateIndex -> INFO 088 Created CouchDB index [indexOwner] in state database [mychannel_marbles] using design document [_design/indexOwnerDoc]

代表索引创建成功

存入一条数据

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","marble1","blue","35","tom"]}'

使用索引进行查询:

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

数据量很少,所以查询速度并不明显,需要关注的是查询参数:

queryMarbles是链码中定义的函数名

{"selector":{"docType":"marble","owner":"tom"}是一个“ad hoc 选择器”,用来查找所有 owner 属性值为 tommarble 记录

"use_index":["_design/indexOwnerDoc", "indexOwner"]指定设计文档名 indexOwnerDoc 和索引名 indexOwner

使用分页:

再新增一些数据

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 方法

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

3表示每页显示3条数据,后面空的参数是bookmark,用来定义从哪个数据开始,返回值如下

[{"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"}}]

返回值当中包含了一个bookmark,可以用于下次查询时传入的参数

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

返回2条数据:

[{"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"}}]

升级和删除索引都不在fabric功能内

升级索引:

curl -i -X POST -H "Content-Type: application/json" -d
       "{\"index\":{\"fields\":[\"docType\",\"owner\"]},
         \"name\":\"indexOwner\",
         \"ddoc\":\"indexOwnerDoc\",
         \"type\":\"json\"}" http://hostname:port/mychannel_marbles/_index

删除索引:

curl -X DELETE http://localhost:5984/mychannel_marbles/_index/indexOwnerDoc/json/indexOwner -H  "accept: */*" -H  "Host: localhost:5984"

转载请注明来源

×

喜欢就点赞,疼爱就打赏