小编给大家分享一下Hyperledger Fabric中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 main
import (
"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/mango
const 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"` //存证hash
FileType 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 = id
card.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) * size
pmap := 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 = 0
for queryIterator.HasNext() {
if next == page*size {
break
}
if next >= index {
item, err := queryIterator.Next()
if err != nil {
return shim.Error("queryIterator.Next 出错")
}
var c CloudCertificate
err = 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.Buffer
buffer.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")
}
}
以上是“Hyperledger Fabric中couchdb丰富查询selector语法有哪些”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。
原文链接:https://my.oschina.net/jonluo/blog/3001053