Hyperledger Fabric V1.0 中日期范围的复合密钥形成
Composite Key formation for a date range in Hyperledger Fabric V1.0
参考this的问题,我也有疑问。
假设我的复合键由字段组成 Owner_id~dateOfcreation
我的钥匙是这样的:
- Owner1~11-05-2017
- Owner1~12-05-2017
- Owner1~13-05-2017
- ...
- ...
- Owner1~30-05-2017
我是否可以获取 date range
的状态,例如 Owner1~12-05-2017 to Owner~27-05-2017
?
根据我的理解,stub.GetStateByRange(startKey,endKey)
将 return 按词法顺序排列的键,因此它不会 return 预期范围。
如果我错了,请纠正我。
我尝试重新排列按键,例如:
- Owner1~2017_05_11
- Owner1~2017_05_12
- Owner1~2017_05_13
- ...
- ...
- Owner1~2017_05_30
在这种情况下,如果我使用
stub.GetStateByPartialCompositeKey('owner~year~month~day',[]string{"owner1","2017","05"})
它将 return 所有以这些范围开头的键。正确吗?
但在这里我也没有得到 date range
.
的确切输出
任何人都可以建议我实现它的正确方法。我觉得是资产共享场景下比较常见的业务场景,请大家帮忙
提前致谢:)
重新阅读您的问题和评论后,我认为您有自己的解决方案。使用函数 GetStateByRange 怎么样?这个函数没有 return 键,它 return 是一个带有值的迭代器。
正如您在上一条评论中所说,我想列出在一个日期范围内创建的所有资产,我将如何从分类帐中查询它。所以,如果我是你,我会使用 GetStateByRange 函数,将日期范围传递给它。
这里我给你贴一个我用过的函数的例子。
func get_all_components(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var err error
fmt.Println("starting get_all_components")
// input sanitation
err = sanitize_arguments_len(args, 1)
if err != nil {
return shim.Error(err.Error())
}
// ---- Get All Components ---- //
resultsIterator, err := stub.GetStateByRange("c0", "c9999999999999999999")
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close()
// buffer is a JSON array containing QueryRecords
var buffer bytes.Buffer
buffer.WriteString("[")
bArrayMemberAlreadyWritten := false
for resultsIterator.HasNext() {
//queryKeyAsStr, queryValAsBytes, err := resultsIterator.Next()
queryResponse, err := resultsIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
// Add a comma before array members, suppress it for the first array member
if bArrayMemberAlreadyWritten == true {
buffer.WriteString(",")
}
buffer.WriteString("{\"Key\":")
buffer.WriteString("\"")
buffer.WriteString(queryResponse.Key)
buffer.WriteString("\"")
buffer.WriteString(", \"Record\":")
// Record is a JSON object, so we write as-is
buffer.WriteString(string(queryResponse.Value))
buffer.WriteString("}")
bArrayMemberAlreadyWritten = true
}
buffer.WriteString("]")
fmt.Printf("get_all_components:\n%s\n", buffer.String())
return shim.Success(buffer.Bytes())
}
您应该在函数调用的参数中传递您的 date range
值。
根据现有评论、采用的解决方案和 API 规范,得出的结论是 stub.GetStateByPartialCompositeKey
最适合 API 此要求。
如果只获取一天的数据,它可以使用 rich query 和 json date_field:value
如果它使用 CouchDB 作为它的状态数据库。由于这不是提交事务,因此在此处使用 rich query 没有问题。
参考this的问题,我也有疑问。
假设我的复合键由字段组成 Owner_id~dateOfcreation
我的钥匙是这样的:
- Owner1~11-05-2017
- Owner1~12-05-2017
- Owner1~13-05-2017
- ...
- ...
- Owner1~30-05-2017
我是否可以获取 date range
的状态,例如 Owner1~12-05-2017 to Owner~27-05-2017
?
根据我的理解,stub.GetStateByRange(startKey,endKey)
将 return 按词法顺序排列的键,因此它不会 return 预期范围。
如果我错了,请纠正我。
我尝试重新排列按键,例如:
- Owner1~2017_05_11
- Owner1~2017_05_12
- Owner1~2017_05_13
- ...
- ...
- Owner1~2017_05_30
在这种情况下,如果我使用
stub.GetStateByPartialCompositeKey('owner~year~month~day',[]string{"owner1","2017","05"})
它将 return 所有以这些范围开头的键。正确吗?
但在这里我也没有得到 date range
.
任何人都可以建议我实现它的正确方法。我觉得是资产共享场景下比较常见的业务场景,请大家帮忙
提前致谢:)
重新阅读您的问题和评论后,我认为您有自己的解决方案。使用函数 GetStateByRange 怎么样?这个函数没有 return 键,它 return 是一个带有值的迭代器。
正如您在上一条评论中所说,我想列出在一个日期范围内创建的所有资产,我将如何从分类帐中查询它。所以,如果我是你,我会使用 GetStateByRange 函数,将日期范围传递给它。
这里我给你贴一个我用过的函数的例子。
func get_all_components(stub shim.ChaincodeStubInterface, args []string) pb.Response {
var err error
fmt.Println("starting get_all_components")
// input sanitation
err = sanitize_arguments_len(args, 1)
if err != nil {
return shim.Error(err.Error())
}
// ---- Get All Components ---- //
resultsIterator, err := stub.GetStateByRange("c0", "c9999999999999999999")
if err != nil {
return shim.Error(err.Error())
}
defer resultsIterator.Close()
// buffer is a JSON array containing QueryRecords
var buffer bytes.Buffer
buffer.WriteString("[")
bArrayMemberAlreadyWritten := false
for resultsIterator.HasNext() {
//queryKeyAsStr, queryValAsBytes, err := resultsIterator.Next()
queryResponse, err := resultsIterator.Next()
if err != nil {
return shim.Error(err.Error())
}
// Add a comma before array members, suppress it for the first array member
if bArrayMemberAlreadyWritten == true {
buffer.WriteString(",")
}
buffer.WriteString("{\"Key\":")
buffer.WriteString("\"")
buffer.WriteString(queryResponse.Key)
buffer.WriteString("\"")
buffer.WriteString(", \"Record\":")
// Record is a JSON object, so we write as-is
buffer.WriteString(string(queryResponse.Value))
buffer.WriteString("}")
bArrayMemberAlreadyWritten = true
}
buffer.WriteString("]")
fmt.Printf("get_all_components:\n%s\n", buffer.String())
return shim.Success(buffer.Bytes())
}
您应该在函数调用的参数中传递您的 date range
值。
根据现有评论、采用的解决方案和 API 规范,得出的结论是 stub.GetStateByPartialCompositeKey
最适合 API 此要求。
如果只获取一天的数据,它可以使用 rich query 和 json date_field:value
如果它使用 CouchDB 作为它的状态数据库。由于这不是提交事务,因此在此处使用 rich query 没有问题。