前言
在1.4版本之后,fabric默认使用CouchDB代替了之前的LevelDB,除了LevelDB支持的键控/合成键/键范围查询之外,CouchDB还支持完整的数据富查询功能,比如针对整个区块链数据的非键查询,因为它的数据内容是以JSON格式存储的,并且是完全可查询的。因此,CouchDB可以满足LevelDB不支持的许多用例的链代码、审计和报告需求
简介
CouchDB是一种NoSQL的解决方案,以键值映射的方式存储文档字段。
它使用
JSON,存储数据(文档),使用java脚本作为其查询语言来转换文档,使用http协议为api访问文档,使用Web浏览器查询索引。
安装部署
前面章节已经讲过在启动byfn.sh脚本的时候docker自动拉取所有必须的镜像,当然也就包括了CoucbDB的镜像
若没有也可以用下面命令安装
# docker pull hyperledger/fabric-couchdb:0.4.21
服务启动
在fabric中CouchDB有两种启动,一种就是普通的docker启动方式,另一种就是使用docker-compose的方式启动,一般而言在fabric中CouchDB都是和peer一一对应,因此都是和peer的配置文件写在一起。例如下面这个yaml文件
services:
couchdb:
container_name: couchdb
image: hyperledger/fabric-couchdb:0.4.21
ports:
- "5984:5984"
peer0.org1.example.com:
container_name: peer0.org1.example.com:1.4.6
hostname: peer0.org1.example.com
image: hyperledger/fabric-peer
environment:
- CORE_LEDGER_STATE_STATEDATABASE=CouchDB
- CORE_LEDGER_STATE_COUCHDBCONFIG_COUCHDBADDRESS=couchdb:5984
#省略后面内容
通过启动Peer服务,一并启动CouchDB,访问地址 http://ip:5984/_utils,页面如下:
各参数说明如下:
| 名称 | 说明 |
|---|---|
| Databases | 数据库及数据表的新增,修改等维护管理 |
| Setup | 配置CouchDB单个peer或多个peer |
| Active Tasks | 正在执行的任务 |
| Configuration | CouchDB的配置参数管理 |
| Replication | CouchDB数据库的备份管理 |
| Documentation | CouchDB教程 |
| Verify | 验证服务是否正常进行 |
| Admin Party | 个人设置 |
当执行官方案例之后可以发现Peer对应的CouchDB数据库中会生成mychannel_、mychannel_lscc和mychannel_mycc 3个数据库
mychannel_
保存通道相关的数据
mychannel_lscc
保存系统链码数据
mychannel_mycc
保存用户链码数据,生成a和b的键值对数据
相关接口
检查数据库是否已经安装和运行
# curl http://ip:5984/
若返回以下结果说明已经运行成功
{"couchdb":"Welcome","version":"2.1.1","features":["scheduler"],"vendor":{"name":"The Apache Software Foundation"}}
查询所有数据库列表
curl -X GET http://ip:5984/_all_dbs
#例如
curl -X GET http://192.168.56.103:5984/_all_dbs
返回值如下
["_replicator","_users","mychannel_","mychannel_lscc","mychannel_mycc"]
获取数据库信息
curl -X GET http://ip:5984/数据库名
#例如
curl -X GET http://192.168.56.103:5984/mychannel_
返回值如下
{
"db_name": "mychannel_",
"purge_seq": "0-g1AAAAEzeJzLYWBg4MhgTmHgzcvPy09JdcjLz8gvLskBCjPlsQBJhgdA6j8QZCUy4FV3AKLuPiF1CyDq9hNS1wBRNx-3uqQEIJlUj9dtSQ4gNfH41SiA1NjjVZPIkCQPUZAFAN6AYvY",
"update_seq": "8-g1AAAAEzeJzLYWBg4MhgTmHgzcvPy09JdcjLz8gvLskBCjMlMiTJ____PyuRAYeCJAUgmWSPX40DSE08fjUJIDX1eNXksQBJhgYgBVQ2n5C6BRB1-7MSmfGqOwBRd5-QeQ8g6oDuY80CAImSYv4",
"sizes": {
"file": 66801,
"external": 9114,
"active": 10931
},
"other": {
"data_size": 9114
},
"doc_del_count": 0,
"doc_count": 2,
"disk_size": 66801,
"disk_format_version": 7,
"data_size": 10931,
"compact_running": false,
"cluster": {
"q": 8,
"n": 1,
"w": 1,
"r": 1
},
"instance_start_time": "0"
}
获取数据库所有文档
curl -X GET http://ip:5984/数据库名/_all_docs
#例如
curl -X GET http://192.168.56.103:5984/mychannel_/_all_docs
返回值如下:
{
"total_rows": 2,
"offset": 0,
"rows": [
{
"id": "resourcesconfigtx.CHANNEL_CONFIG_KEY",
"key": "resourcesconfigtx.CHANNEL_CONFIG_KEY",
"value": {
"rev": "3-fb17e8d74af2a55232a3d67c5cec1e99"
}
},
{
"id": "statedb_savepoint",
"key": "statedb_savepoint",
"value": {
"rev": "5-9cf6b652cc24b4f2c8aa34fa776de685"
}
}
]
}
查询某个文档
curl -X GET http://ip:5984/数据库名/文档id
#例如
curl -X GET http://192.168.56.103:5984/mychannel_/statedb_savepoint
返回值如下:
{
"_id": "statedb_savepoint",
"_rev": "5-9cf6b652cc24b4f2c8aa34fa776de685",
"BlockNum": 4,
"TxNum": 0
}
若id值有特殊符号\u0000的格式,则需要这样查询
#错误的查询方式
curl -X GET http://192.168.56.103:5984/mychannel_/mycc\u0000a
#报错信息
{"error":"not_found","reason":"missing"}
#正确的查询方式,把\u0000替换为%00
curl -X GET http://192.168.56.103:5984/mychannel_/mycc%00a
创建数据库
curl -X PUT http://ip:5984/数据库名
#例如
curl -X PUT http://192.168.56.103:5984/test
返回值如下:
{"ok":true}
删除数据库
curl -X DELETE http://ip:5984/数据库名字
#例如
curl -X DELETE http://192.168.56.103:5984/test
返回值如下:
{"ok":true}
添加文档
curl -H "Content-Type:application/json" -X POST http://ip:5984/数据库名 -d'{"_id":"xxx","name":"xxx"}'
#例如
curl -H "Content-Type:application/json" -X POST http://192.168.56.103:5984/test -d'{"_id":"1","name":"hongcb"}'
返回值如下:
{
"ok": true,
"id": "1",
"rev": "1-43e0746f39bf436468609140d71e04c5"
}
修改文档
curl -X PUT http://ip:5984/数据库名/文档id -d '{"_id":"xxx","_rev":"要一致","name":"xxx","title":"xxx"}'
#例如
curl -X PUT http://192.168.56.103:5984/test/1 -d '{"_id":"1","_rev":"1-43e0746f39bf436468609140d71e04c5","name":"hongcb2","title":"hhhh"}'
返回值如下:
{
"ok": true,
"id": "1",
"rev": "2-43c90eac47980abc776ea3fdf6564019"
}
删除文档
curl -X DELETE http://ip:5984/数据库名/文档id?rev=要一致
#例如
curl -X DELETE http://192.168.56.103:5984/test/1?rev=2-43c90eac47980abc776ea3fdf6564019
返回值如下:
{
"ok": true,
"id": "1",
"rev": "3-e7978ecfd4c68ea65cc8098d7815ad9b"
}