《HyperLedger Fabric 实战》—— 八、CouchDB
1、启动部署
CouchDB 通过 peer.yaml 文件配置实现启动:
services:
couchdb:
container_name: couchdb
image: hyperledger/fabric-couchdb
environment:
- COUCHDB_USER=admin
- COUCHDB_PASSWORD=123456
# Comment/Uncomment the port mapping if you want to hide/expose the CouchDB service,
# for example map it to utilize Fauxton User Interface in dev environments.
ports:
- "5984:5984"
foo27.org2.example.com:
container_name: foo27.org2.example.com
image: hyperledger/fabric-peer
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984
- CORE_LEDGER_STATE_COUCHDBCONFIG_USERNAME=admin
- CORE_LEDGER_STATE_COUCHDBCONFIG_PASSWORD=123456
- CORE_PEER_ID=foo27.org2.example.com
- CORE_PEER_NETWORKID=aberic
- CORE_PEER_ADDRESS=foo27.org2.example.com:7051
- CORE_PEER_CHAINCODEADDRESS=foo27.org2.example.com:7052
- CORE_PEER_CHAINCODELISTENADDRESS=foo27.org2.example.com:7052
- CORE_PEER_GOSSIP_EXTERNALENDPOINT=foo27.org2.example.com:7051
- CORE_PEER_LOCALMSPID=Org2MSP
- CORE_VM_ENDPOINT=unix:///host/var/run/docker.sock
# the following setting starts chaincode containers on the same bridge network as the peers
# https://docs.docker.com/compose/networking/
- CORE_VM_DOCKER_HOSTCONFIG_NETWORKMODE=aberic_default
- CORE_VM_DOCKER_TLS_ENABLED=false
# - CORE_LOGGING_LEVEL=ERROR
- CORE_LOGGING_LEVEL=DEBUG
- CORE_PEER_GOSSIP_SKIPHANDSHAKE=
- CORE_PEER_GOSSIP_USELEADERELECTION=
- CORE_PEER_GOSSIP_ORGLEADER=
- CORE_PEER_PROFILE_ENABLED=
- CORE_PEER_TLS_ENABLED=
- CORE_PEER_TLS_CERT_FILE=
- CORE_PEER_TLS_KEY_FILE=
- CORE_PEER_TLS_ROOTCERT_FILE=
volumes:
- /var/run/:/host/var/run/
- ./chaincode/go/:/opt/gopath/src/github.com/hyperloedger/fabric/chaincode/go
- ./crypto-config/peerOrganizations/org2.example.com/peers/foo27.org2.example.com/msp/:/etc/hyperledger/fabric/msp
- ./crypto-config/peerOrganizations/org2.example.com/peers/foo27.org2.example.com/tls:/etc/hyperledger/fabric/tls
working_dir: /opt/gopath/src/github.com/hyperledger/fabric/peer
command: peer node start
ports:
- 7051:7051
- 7052:7052
- 7053:7053
depends_on:
- couchdb
networks:
default:
aliases:
- aberic
其中 CORE_LEOGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984
的值有两个,分别是 “goleveldb” 和 “CouchDB”
建议通过上面的变量在与 peer 节点相同的服务器上运行 CouchDB,而不是将 CouchDB 容器端口映射到 Docker-Compose 中的服务器端口,否则必须在 CouchDB 客户端和服务器之间的连接上提供适当的安全性。
CouchDB 访问地址: ip:port/_utils
2、索引应用
marbles02 位于 fabric/examples/chaincode/go 目录下,将该目录上传服务器的 chaincode/go 目录下。
安装并实例化该智能合约后,初始化一个名为 marble1 且所有者为 tom 的对象:
peer chaincode install -n marble1 -p github.com/hyperledger/fabric/aberic/chaincode/go/marbles02 -v 1.0
peer chaincode instantiate -o orderer.example.com:7050 -C mychannel -n marble1 -c '{"Args":[]}' -P "OR ('Org1MSP.member', 'Org2MSP.member')" -v 1.0
peer chaincode invoke -C mychannel -n marble1 -c '{"Args":["initMarble","marble1","blue","35","tom"]}'
查询
peer chaincode query -C mychannel -n marble1 -c '{"Args":["readMarble","marble1"]}'
初始化名为 marble2 和 marble3 且所有者为 tom 的对象:
peer chaincode invoke -C mychannel -n marble1 -c '{"Args":["initMarble","marble2","red","50","tom"]}'
peer chaincode invoke -C mychannel -n marble1 -c '{"Args":["initMarble","marble3","blue","70","tom"]}'
查询所有者为 tom 的对象
peer chaincode query -C mychannel -n marble1 -c '{"Args":["queryMarblesByOwner","tom"]}'
依次点击 mychannel_marble1 -> marble1 可查看到初始化 marble1 时的所有参数,这条数据也与初始化方法 initMarble 所做一致,具体的 initMarble 源码可参考源码。
3、CouchDB 创建索引 p215
1)Post 方式
curl -i -X POST -H "Content-Type: application/json" -d "{\"index\":{\"fields\":[\"name\",\"color\"]},\"name\":\"indexColor\",\"ddoc\":\"indexColorDoc\",\"type\":\"json\"}" http://192.168.24.251:5984/mychannel_marble1/_index
在对 CouchDB 的 restful 接口发送请求的时候,如果 CouchDB 设置了用户名和密码,则必须在 http:// 后,和 ip 前加上 “username:password@”,才能以合法的登录状态执行接口。see: http://admin:123456@192.168.24.251:5984…。
2)CouchDB 页面创建
进入 mychannel_marble1 后,在左侧 All Documents 右面,点击 “+” 号,选择 “Mango Indexs”。
进入索引集合页面后,右侧是已经创建好的索引列表,左侧是新建索引的操作区,点击上部的下拉框,可选择单字段或多字段的预置模板,这里我们选择 “Multiple fields(json)”,粘入以下内容,并点击 “Create index”,便创建了一条字段为 “name, size” 的索引。
{
"index": {
"fields": [
"name",
"size"
]
},
"name": "indexSize",
"ddoc": "indexSizeDoc",
"type": "json"
}
4、CouchDB Json 参数
查询 json 参数
参 数 | 类 型 | 描 述 |
---|---|---|
selector | json | Json对象描述用于选择文档的标准。是必备参数 |
limit | number | 返回的最大结果数。默认 25。是可选参数 |
skip | number | 路过第一个“n”结果,其中“n”是指定的值。是可选参数 |
sort | json | Json数组遵循的排序语法。是可选参数 |
fields | array | Json数组,指定每个对象的哪些字段应该返回。如果省略了,就返回整个对象。是可选参数 |
use_index | string|array | 指示一个查询使用一个特定的索引。指定为“<design_document>”或["<design_document>","<index_name"]。是可选参数 |
r | number | 读取结果所需的文档数量。默认为 1,在这种情况下,在索引中找到的文档会返回。如果设置为更高的值,那么每份文档至少在返回结果之前的许多副本中读取。这可能需要花费更多的时间,而不仅仅是使用索引本地存储的文档。 可选参数,默认值 1 |
bookmark | string | 这是一个字符串,它使用户能够指定所需要的结果页面,用于通过结果集进行分页。每个查询都会在书签 key 下返回一个不透明的字符串,然后在查询中返回,以获得下一页的结果。如果选择器查询的任何部分在请求之间发生变化,那么结果是未定义的。是可选参数 |
update | boolean | 是否在返回结果之前更新索引。默认 true。是可选参数 |
stable | boolean | 视力的结果是否应该从“稳定版”一组集合中返回,是可选参数 |
stale | string | update=false 和 stable=true 选项,可能赋值:“ok”。是可选参数 |
execution_stats | boolean | 在查询回复中包含执行统计信息,默认为 false。可选参数 |
返回 参数集
参 数 | 类 型 | 描 述 |
---|---|---|
docs | object | 匹配搜索的文档数组。在每一个匹配的文档中,列出了请求正文部分中指定的字段,以及它们的值 |
warning | string | 警告内容 |
execution_stats | object | 统计数据对象 |
返回 状态集
参 数 | 类 型 | 描 述 |
---|---|---|
200 | OK | 请求成功完成 |
400 | Bad Request | 无效的请求 |
401 | Unauthorized | 读权限请求 |
500 | Internal Server Error | 查询执行错误 |
5、选择器语法
1)匹配所有“director”字段中具有“Lars von Trier” 值的文档。
{
"director": "Lars von Trier"
}
"selector": {
"$text": "Bond"
},
"fields": [
"title", "cast"
]
2)名称字段带有“Paul”,且有一个值“Boston”的位置字段
{
"name": "Paul,
"location": "Boston"
}
3)字段和子字段选择器
{
"imdb": {
"rating": 8
}
}
可缩写成如下方式
{
"imdb.rating": 8
}
组合运算符参数
运算符 | 参数类型 | 备 注 |
---|---|---|
$and | Array | 数组中的所有选择器匹配,则匹配 |
$or | Array | 数组中的任何选择器匹配,则匹配。所有选择器必须使用相同的索引 |
$not | Selector | 给定的选择器不匹配的话 |
$nor | Array | 数组中的选择器没有匹配的话 |
$all | Array | 包含参数数组的所有元素,则匹配数组值 |
$elemMatch | Selector | 匹配并返回包含数组字段的所有文档,其中至少有一个与所有指定查询条件匹配的元素 |
$allMatch | Selector | 匹配并返回包含数组字段的所有文档,其中所有元素都匹配所有指定的查询条件 |
条件运算符参数
运算符类型 | 运算符 | 参 数 |
---|---|---|
$lt | ||
$lte | ||
$eq | ||
$ne | ||
$gte | ||
$gt | ||
$exists | ||
$type | ||
$in | ||
$nin | ||
$size | ||
$mod | ||
$regex |
工