zoukankan      html  css  js  c++  java
  • 在Fabric链码中进行前缀批查询

    用过Fabric的都知道,在Fabric中的状态数据库提供了Couchdb和Leveldb两种实现,一般我们都会使用Couchdb作为状态数据库的默认实现,主要是因为Couchdb可以进行富查询。但是在某些情况下我们只能采用Leveldb的情况下,我们无法使用富查询,那么怎么办?我们可以利用Leveldb适合前缀查询的特点进行前缀查询,而且由于Leveldb底层结构的特点,进行前缀查询的效率是特别高的。

    要进行前缀查询,那么我们在PutState的时候要合理设计前缀值,从而能够利用前缀查询。以一个会议签到存证系统为例,我们在Fabric的链码中设计了两个对象Meeting和CheckinLog。

    会议对象Meeting的存证我们设计Key为:“Meeting_”+会议ID,然后PutState将会议的JSON存入Fabric中。

    签到记录对象CheckinLog的存证,我们设计Key为:”Checkin_”+会议ID+”_”+用户ID,然后调用PutState将CheckinLog这个对象的Json作为Value存入到Fabric中。

    接下来是对某个会议的签到记录的查询了。这么我们知道会议ID的情况下,查询签到记录返回的是一个集合,那么我们可以基于stub.GetStateByRange接口来进行查询,该操作的核心就是要构造其两个参数startKey和endKey。以下是代码实现,主要用到了BytesPrefix函数用于计算endKey,该函数是在github.com/syndtr/goleveldb/leveldb/util有的,我们直接摘抄出来即可。

    //根据会议ID,返回本次会议的签到记录列表
    func QueryCheckinLogsByMeetingId(stub shim.ChaincodeStubInterface, meetingId int) ([]*CheckinLog, error) {
        startKey:=fmt.Sprintf( "Checkin_%d_",meetingId)
        endKey:=string(BytesPrefix([]byte(startKey)))
        resultsIterator, err:= stub.GetStateByRange(startKey,endKey)
        defer resultsIterator.Close()
        if err != nil {
            return nil, err
        }
        result:=[]*CheckinLog{}
        for resultsIterator.HasNext() {
            queryResponse,err:= resultsIterator.Next()
            if err != nil {
                return nil, err
            }
            row:=&CheckinLog{}
            json.Unmarshal(queryResponse.Value,row)
            result=append(result,row)
        }
        return result, nil
    }
    
    //计算GetStateByRange时的endKey,该函数摘自:github.com/syndtr/goleveldb/leveldb/util
    func BytesPrefix(prefix []byte) []byte {
        var limit []byte
        for i := len(prefix) - 1; i >= 0; i-- {
            c := prefix[i]
            if c < 0xff {
                limit = make([]byte, i+1)
                copy(limit, prefix)
                limit[i] = c + 1
                break
            }
        }
        return limit
    }

    就是这样的逻辑,我们就可以在Fabric链码中通过前缀进行批量查询。

  • 相关阅读:
    mysqlp批量替换的sql语句
    Paypal 支付功能的 C# .NET / JS 实现
    Layui table 组件的使用:初始化加载数据、数据刷新表格、传参数
    WinForm DataGridView 绑定泛型List(List<T>)/ArrayList不显示的原因和解决
    entity framework codefirst 用户代码未处理DataException,InnerException基础提供程序在open上失败,数据库生成失败
    《设计模式》一书中的23种设计模式
    C++程序实例唯一方案,窗口只打开一次,程序只打开一次
    重构——与设计模式的恋情
    重构——一个小例子
    C#通过调用WinApi打印PDF文档类,服务器PDF打印、IIS PDF打印
  • 原文地址:https://www.cnblogs.com/studyzy/p/14145027.html
Copyright © 2011-2022 走看看