为什么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 语法相关推荐

  1. 《HyperLedger Fabric 实战》—— 十、项目演练 -- 反欺诈系统

    <HyperLedger Fabric 实战>-- 十.项目演练 – 反欺诈系统 注意点 1.用户唯一ID应该是姓名与身份证号组合后的MD5,这样可以防止加盟用户仅通过机器生成的大量身份证 ...

  2. hyperledger fabric 实战开发——水产品溯源交易平台(二)

    文章目录 前言 一.技术学习 1.Hyperledger fabric 1.1 流程 1.2 配置 1.3 范例解析并自写 1.3 算法实现 二.Web编写 前言 hyperledger fabric ...

  3. Fabric 超级账本学习【8】Hyperledger Fabric 实战——基于区块链的学历学位系统

    文章目录 摘要 安装部署 基于区块链的学历学位系统 报错1如下 报错原因:config.yaml 配置文件中的证书路径错误 访问基于区块链的学历学位系统 登录 基于区块链的学历学位系统 添加高等教育学 ...

  4. hyperledger fabric 实战开发——水产品溯源交易平台(一)

    文章目录 前言 环境准备 水产品溯源交易平台设计 实现步骤 1. 模板获取 2. 模板修改 虚拟机优化(根据个人喜好选择) 前言 在万字解析--区块链hyperledger fabric2.2部署实战 ...

  5. hyperledger fabric如何连接couchdb并通过宿主机浏览器访问couchdb

    本文适用于linux环境并基于docker容器 假设VMware虚拟机的ip为:192.168.142.130 首先创建docker-compose-couch.yaml文件,并编译以下内容: ver ...

  6. Hyperledger Fabric 实战(十二): Fabric 源码本地调试

    借助开发网络调试 fabric 源码本地调试 准备工作 IDE Goland Go 1.9.7 fabric-samples 模块 chaincode-docker-devmode fabric 源码 ...

  7. Hyperledger Fabric 实战(七):链码 shim API 详解

    为什么80%的码农都做不了架构师?>>>    用 Go 的链码的 shim API 主要方法详解 GetFunctionAndParameters 获取方法名和参数 invoke的 ...

  8. Hyperledger Fabric 2.0 官方文档中文版 第6章 教程(下)

    Hyperledger Fabric 2.0 官方文档中文版 第6章 教程下 总目录 6.教程(下) 使用CouchDB 为什么使用CouchDB? 在Hyperledger Fabric中启用Cou ...

  9. Hyperledger Fabric CouchDB 查询

    Hyperledger Fabric(HLF) 使用一个KV数据库存储它的状态.这个对象存储包含可以使用它的键查询的二进制数据.fabric 默认使用LevelDB存储,它包含在 peer 进程中. ...

  10. Hyperledger Fabric 1.2.1启用CouchDB作为状态数据库

    一. CouchDB 状态数据库可选类型包括LevelDB和CouchDB.LevelDB是嵌入在peer进程中的默认键/值状态数据库,CouchDB是一个可选的外部状态数据库.与LevelDB键/值 ...

最新文章

  1. 数值分析上机题matlab线性方程组,数值分析上机实验报告 - 线性方程组部分实验题1...
  2. 冲刺第八天 12.4 TUE
  3. java set iterator_Java中的TreeSet的iterator()方法 Java.util.TreeSet.iterator() - Break易站
  4. java数据分析库,威力加强版
  5. C#LeetCode刷题之#874-模拟行走机器人​​​​​​​(Walking Robot Simulation)
  6. Kotlin学习笔记 第二章 类与对象 第十二 十三节 对象表达式与对象声明 类型别名
  7. DP+BIT(优化复杂度) UESTC 1217 The Battle of Chibi
  8. matlab R2017b 初始化缓慢的问题
  9. python搭建图书管理系统
  10. 数据仓库分层设计思想
  11. win10安装Adobe 2022全新体验安装教程 你觉得到底香不香
  12. PHR-search:一个基于预测蛋白质层次关系的蛋白质远程同源性检测搜索框
  13. @RequestBody注解的简单用法
  14. 开源的去马赛克神器 修复受损漫画无压力
  15. 多线程结果合并计算CyclicBarrier的使用
  16. html 设置两个标签的相对距离_HTML 让上下两个DIV之间保持一定距离或没有距离...
  17. Mac OS 任意显示器 开启HiDPI方法
  18. 五大要求让BPM与企业对接
  19. LenNet5-MNIST
  20. 游戏外挂防封心得防检测防封技术

热门文章

  1. 阶段1 语言基础+高级_1-3-Java语言高级_06-File类与IO流_05 IO字符流_2_字符输入流读取字符数据...
  2. 网络编程基础,传输层服务
  3. idea生成get/set方法
  4. 旧板与IO板之间的连接
  5. Grasshopper 2.0 MP Color FireWire 1394b (Sony ICX274)
  6. android 设置editext只能输入数字
  7. 章节四、1-if条件语句
  8. 【网络流24题】分配问题 最小最大费用最大流
  9. iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄...
  10. codeforce 604B More Cowbell