富查詢的使用
鏈碼中的數據存儲都是基於K-V鍵值對的形式,通常來講,是保存在LevelDB中。可是目前Fabric支持鏈碼使用couchDB進行存儲數據、經過編寫富查詢的方式查詢數據。shell
認識第一個富查詢語句
富查詢語句是一種特定的json格式,以下所示:json
{ "selector": { "coin": 100 } }
selector對應一個列表,列表包含多個單元,每一個單元匹配一個字段,譬如上述中匹配的是知足餘額爲100的User數據網絡
在鏈碼中實現富查詢
- 在first_cc目錄下,建立couchDB索引目錄和索引文件
# 建立索引目錄 mkdir -p META-INF/statedb/couchdb/indexes # 建立基於coin字段的索引文件 touch META-INF/statedb/couchdb/indexes/indexCoin.json
- 給索引文件indexCoin.json添加以下內容
{ "index": { "fields": [ "coin" ] }, "ddoc": "indexCoinDoc", "name": "indexCoin", "type": "json" }
- 在first_cc.go文件中實現基於coin值進行富查詢的UserQueryByCoin函數
// 基於coin值進行用戶查詢 func UserQueryByCoin(stub shim.ChaincodeStubInterface, args []string) pb.Response { // 判斷參數個數 if len(args) != 1 { return shim.Error("args must be one") } // 編寫富查詢語句,根據coin值進行匹配查詢 var queryString = fmt.Sprintf(`{"selector":{"coin": %v}}`, args[0]) // 查詢結果的變量定義 var users = make([]User, 0) // 富查詢操做,返回一個迭代器 iterator, err := stub.GetQueryResult(queryString) if err != nil { fmt.Println(err.Error()) return shim.Error("data get failed: " + err.Error()) } // defer後面的操做是函數執行退出以前的會進行的操做,這裏是關閉迭代器 defer iterator.Close() // 循環獲取迭代器中的值 for ; iterator.HasNext(); { resp, err := iterator.Next() if err != nil { fmt.Println(err.Error()) return shim.Error("data get failed: " + err.Error()) } // 將迭代器的值取出反序列化,存入查詢結果中 var user User if err := json.Unmarshal(resp.Value, &user); err != nil { fmt.Println(err.Error()) return shim.Error("data unmarshal failed: " + err.Error()) } users = append(users, user) } // 將查詢結果序列化 data, err := json.Marshal(users) if err != nil { fmt.Println(err.Error()) return shim.Error("data marshal failed: " + err.Error()) } fmt.Println(string(data)) return shim.Success(data) }
- 在Invoke中添加函數調用
// 修改以前實現的Invoke()方法 func (t *FirstChainCode) Invoke(stub shim.ChaincodeStubInterface) pb.Response { /* 獲取參數,分解爲調用方法名,以及傳入的參數列表 而後根據具體的function,調用對應的以前寫過的函數 */ function, args := stub.GetFunctionAndParameters() switch function { case "UserRegister": return UserRegister(stub, args) case "UserQuery": return UserQuery(stub, args) case "UserQueryByCoin": return UserQueryByCoin(stub, args) default: return shim.Error("no this function name.") } }
測試使用了couchDB的鏈碼
MockStub測試不能支持使用了couchDB的鏈碼,所以若是須要測試富查詢的相關函數是否正確,須要模擬搭建一套fabric網絡,peer使用dev調試模式,對鏈碼進行實時調式並測試。相關說明請見
Hyperledger Fabric學習(十)智能合約(鏈碼)devplat工具測試
app
- 使用devplat搭建fabric平臺,並安裝實例化部署好first_cc鏈碼
- 調用UserQueryByCoin方法查詢結果