Hyperledger Fabric 实战(八):couchdb 丰富查询 selector 语法
为什么80%的码农都做不了架构师?>>>
Couchdb 查询 Selector 选择器语法
组合字符列表:
- "$and" - 数组参数
- "$or" - 数组参数
- "$not" - 单一参数
- "$nor" - 数组参数
- "$all" - 数组参数(数组值的特殊运算符)
- "$elemMatch" - 单一参数(数组值的特殊运算符)
条件参数列表:
平等运算符
- "$lt" - 任意 JSON
- "$lte" - 任意 JSON
- "$eq" - 任意 JSON
- "$ne" - 任意 JSON
- "$gte" - 任意 JSON
- "$gt" - 任意 JSON
对象相关运算符
- "$exists" - 布尔值,检查字段是否存在,无论其值如何
- "$type" - 字符串,检查文档字段的类型
数组相关运算符
- "$in" - JSON值数组,文档字段必须存在于提供的列表中
- "$nin" - JSON值数组,文档字段不得存在于提供的列表中
- "$size" - 整数,特殊条件,用于匹配文档中数组字段的长度。非数组字段无法匹配此条件。
其他相关运营商
- "$mod" - [Divisor,Remainder],其中Divisor和Remainder都是正整数(即大于0)。匹配文档where(field%Divisor == Remainder)为true。对于任何非整数字段,这都是错误的
- "$regex" - 字符串,与文档字段匹配的正则表达式模式。仅当字段为字符串值并与提供的匹配项匹配时才匹配
最简单的选择器
{"selector":{"name":"tom"}}
其中
{"name":"tom"}
匹配 name 为 tom 的文档(如果存在)。使用其他字段扩展此示例可能如下所示:
{"name": "tom", "location": "Boston"}
这将匹配一个 name 叫 tom 的文件和拥有 Boston 的 location 值。
如果选择器中的对象键有两个特殊的语法元素(句号或简称)字符表示文档中的子字段。例如,这是两个相同的例子:
{"location": {"city": "Omaha"}}
{"location.city": "Omaha"}
如果对象的键包含句号,则可以使用反斜杠进行转义,即
{"location\\.city": "Omaha"}
请注意,这里需要双反斜杠来编码实际的单反斜杠。
第二个重要的语法元素是使用美元符号($)前缀来表示运算符。例如:
{"age": {"$gt": 21}}
在这个例子中创建了布尔表达式 age > 21 。
大多数形式是隐式运算符
在大多数情况下,每个操作员必须具有该形式{"$operator": argument}。虽然选择器有两个隐式运算符。
首先,任何不是条件运算符参数的JSON对象都是 $and 每个字段的隐式运算符。例如,这两个例子是相同的:
{"foo": "bar", "baz": true}
{"$and": [{"foo": {"$eq": "bar"}}, {"baz": {"$eq": true}}]}
所以任何包含没有运算符的JSON值的字段都是相等的条件。例如,这些是等价的:
{"foo": "bar"}
{"foo": {"$eq": "bar"}}
需要明确的是,这些也是等效的:
{"foo": {"bar": "baz"}}
{"foo": {"$eq": {"bar": "baz"}}}
虽然,前面的例子实际上会在内部标准化为:
{"foo.bar": {"$eq": "baz"}}
CouchDB 使用了MongoDB 的查询语言 Mango ,具体可以查看https://github.com/cloudant/mango
一个Couchdb丰富查询实战的chaincode
package mainimport ("fmt"/*导入 chaincode shim 包和 peer protobuf 包*/"github.com/hyperledger/fabric/core/chaincode/shim""github.com/hyperledger/fabric/protos/peer""encoding/json""time""strconv""bytes""strings"
)//参考: https://github.com/cloudant/mangoconst prefix = "jonluo"type CloudCertificateChaincode struct {
}// 云证
type CloudCertificate struct {CloudCardNumber string `json:"cloudCardNumber"` //云证编号CloudCardPerson string `json:"cloudCardPerson"` //存证方CloudCardPlatform string `json:"cloudCardPlatform"` //传证平台Time int64 `json:"time"` //存证时间BlockNumber string `json:"blockNumber"` //存证区块号CloudCardHash string `json:"cloudCardHash"` //存证hashFileType string `json:"fileType"` //文件类型FileLabel string `json:"fileLabel"` //文件标签FileName string `json:"fileName"` //文件名FileAddress string `json:"fileAddress"` //下载地址
}//初始化方法
func (s *CloudCertificateChaincode) Init(stub shim.ChaincodeStubInterface) peer.Response {return shim.Success(nil)
}//调用Chaincode
func (s *CloudCertificateChaincode) Invoke(stub shim.ChaincodeStubInterface) peer.Response {//获取要调用的方法名和方法参数fn, args := stub.GetFunctionAndParameters()fmt.Printf("方法: %s 参数 : %s \n", fn, args)if fn == "addCard" {return s.addCard(stub, args)} else if fn == "getList" {return s.getList(stub, args)} else if fn == "get" {return s.get(stub, args)}return shim.Error("方法不存在")
}func (s *CloudCertificateChaincode) addCard(stub shim.ChaincodeStubInterface, args []string) peer.Response {if len(args) != 1 {return shim.Error("参数出错")}cardStr := args[0]var card CloudCertificate//这里就是实际的解码和相关的错误检查if err := json.Unmarshal([]byte(cardStr), &card); err != nil {return shim.Error("json反序列化失败")}t := time.Now()id := prefix + strconv.FormatInt(t.UnixNano(), 10)card.CloudCardNumber = idcard.Time = t.Unix()bys, err := json.Marshal(card)fmt.Println("json:" + string(bys))if err != nil {return shim.Error("json序列化失败")}err = stub.PutState(id, bys)if err != nil {return shim.Error(err.Error())}return shim.Success(nil)
}func (s *CloudCertificateChaincode) getList(stub shim.ChaincodeStubInterface, args []string) peer.Response {if len(args) != 3 {return shim.Error("要输入一个键")}page, err := strconv.Atoi(args[0])if err != nil {return shim.Error("page 出错")}size, err := strconv.Atoi(args[1])if err != nil {return shim.Error("size 出错")}index := (page - 1) * sizepmap := map[string]string{}if err := json.Unmarshal([]byte(args[2]), &pmap); err != nil {return shim.Error("json反序列化失败")}//封装条件selector := selectionCriteria(pmap)fmt.Println(selector)queryIterator, err := stub.GetQueryResult(selector)defer queryIterator.Close()var list = make([]CloudCertificate, 0)if err != nil {return shim.Error("GetQueryResult 出错")} else {var next = 0for queryIterator.HasNext() {if next == page*size {break}if next >= index {item, err := queryIterator.Next()if err != nil {return shim.Error("queryIterator.Next 出错")}var c CloudCertificateerr = json.Unmarshal(item.Value, &c)if err != nil {return shim.Error("json反序列化失败")}list = append(list, c)}next++}}msg, err := json.Marshal(list)fmt.Println("json:" + string(msg))if err != nil {return shim.Error("json序列化失败")}return shim.Success(msg)}func (s *CloudCertificateChaincode) get(stub shim.ChaincodeStubInterface, args []string) peer.Response {if len(args) != 1 {return shim.Error("要输入一个键")}//读出value, err := stub.GetState(args[0])if err != nil {return shim.Error(err.Error())}return shim.Success(value)
}func selectionCriteria(pmap map[string]string) string {var buffer bytes.Bufferbuffer.WriteString(`{"selector":{`)buffer.WriteString(`"cloudCardNumber":{"$regex": "^` + prefix + `.*"},`)for k, v := range pmap {switch k {case "startTime":if v != "" {buffer.WriteString(`"time":{"$gte": ` + v + `},`)}case "endTime":if v != "" {buffer.WriteString(`"time":{"$lte": ` + v + `},`)}case "startTime-endTime":if v != "" {args := strings.Split(v,"-")buffer.WriteString(`"time":{"$gte": ` + args[0] + `,"$lte": ` + args[1] + `},`)}case "fileType":if v != "" && v != "," {types := `"fileType":{"$or":[`args := strings.Split(v,",")for i,tyv := range args {if i != 0 {types += `,`}types +=`{"$eq":"`+tyv+`"}`}types += `]},`buffer.WriteString(types)}default:if k != "" && v != "" {buffer.WriteString(`"` + k + `":{"$eq": "` + v + `"},`)}}}buffer.Truncate(buffer.Len()-1)buffer.WriteString("}}")return buffer.String()
}func main() {if err := shim.Start(new(CloudCertificateChaincode)); err != nil {fmt.Println("CloudCertificateChaincode start error")}
}
转载于:https://my.oschina.net/jonluo/blog/3001053
Hyperledger Fabric 实战(八):couchdb 丰富查询 selector 语法相关推荐
- 《HyperLedger Fabric 实战》—— 十、项目演练 -- 反欺诈系统
<HyperLedger Fabric 实战>-- 十.项目演练 – 反欺诈系统 注意点 1.用户唯一ID应该是姓名与身份证号组合后的MD5,这样可以防止加盟用户仅通过机器生成的大量身份证 ...
- hyperledger fabric 实战开发——水产品溯源交易平台(二)
文章目录 前言 一.技术学习 1.Hyperledger fabric 1.1 流程 1.2 配置 1.3 范例解析并自写 1.3 算法实现 二.Web编写 前言 hyperledger fabric ...
- Fabric 超级账本学习【8】Hyperledger Fabric 实战——基于区块链的学历学位系统
文章目录 摘要 安装部署 基于区块链的学历学位系统 报错1如下 报错原因:config.yaml 配置文件中的证书路径错误 访问基于区块链的学历学位系统 登录 基于区块链的学历学位系统 添加高等教育学 ...
- hyperledger fabric 实战开发——水产品溯源交易平台(一)
文章目录 前言 环境准备 水产品溯源交易平台设计 实现步骤 1. 模板获取 2. 模板修改 虚拟机优化(根据个人喜好选择) 前言 在万字解析--区块链hyperledger fabric2.2部署实战 ...
- hyperledger fabric如何连接couchdb并通过宿主机浏览器访问couchdb
本文适用于linux环境并基于docker容器 假设VMware虚拟机的ip为:192.168.142.130 首先创建docker-compose-couch.yaml文件,并编译以下内容: ver ...
- Hyperledger Fabric 实战(十二): Fabric 源码本地调试
借助开发网络调试 fabric 源码本地调试 准备工作 IDE Goland Go 1.9.7 fabric-samples 模块 chaincode-docker-devmode fabric 源码 ...
- Hyperledger Fabric 实战(七):链码 shim API 详解
为什么80%的码农都做不了架构师?>>> 用 Go 的链码的 shim API 主要方法详解 GetFunctionAndParameters 获取方法名和参数 invoke的 ...
- Hyperledger Fabric 2.0 官方文档中文版 第6章 教程(下)
Hyperledger Fabric 2.0 官方文档中文版 第6章 教程下 总目录 6.教程(下) 使用CouchDB 为什么使用CouchDB? 在Hyperledger Fabric中启用Cou ...
- Hyperledger Fabric CouchDB 查询
Hyperledger Fabric(HLF) 使用一个KV数据库存储它的状态.这个对象存储包含可以使用它的键查询的二进制数据.fabric 默认使用LevelDB存储,它包含在 peer 进程中. ...
- Hyperledger Fabric 1.2.1启用CouchDB作为状态数据库
一. CouchDB 状态数据库可选类型包括LevelDB和CouchDB.LevelDB是嵌入在peer进程中的默认键/值状态数据库,CouchDB是一个可选的外部状态数据库.与LevelDB键/值 ...
最新文章
- 数值分析上机题matlab线性方程组,数值分析上机实验报告 - 线性方程组部分实验题1...
- 冲刺第八天 12.4 TUE
- java set iterator_Java中的TreeSet的iterator()方法 Java.util.TreeSet.iterator() - Break易站
- java数据分析库,威力加强版
- C#LeetCode刷题之#874-模拟行走机器人​​​​​​​(Walking Robot Simulation)
- Kotlin学习笔记 第二章 类与对象 第十二 十三节 对象表达式与对象声明 类型别名
- DP+BIT(优化复杂度) UESTC 1217 The Battle of Chibi
- matlab R2017b 初始化缓慢的问题
- python搭建图书管理系统
- 数据仓库分层设计思想
- win10安装Adobe 2022全新体验安装教程 你觉得到底香不香
- PHR-search:一个基于预测蛋白质层次关系的蛋白质远程同源性检测搜索框
- @RequestBody注解的简单用法
- 开源的去马赛克神器 修复受损漫画无压力
- 多线程结果合并计算CyclicBarrier的使用
- html 设置两个标签的相对距离_HTML 让上下两个DIV之间保持一定距离或没有距离...
- Mac OS 任意显示器 开启HiDPI方法
- 五大要求让BPM与企业对接
- LenNet5-MNIST
- 游戏外挂防封心得防检测防封技术
热门文章
- 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_2_字符输入流读取字符数据...
- 网络编程基础,传输层服务
- idea生成get/set方法
- 旧板与IO板之间的连接
- Grasshopper 2.0 MP Color FireWire 1394b (Sony ICX274)
- android 设置editext只能输入数字
- 章节四、1-if条件语句
- 【网络流24题】分配问题 最小最大费用最大流
- iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄...
- codeforce 604B More Cowbell