英文:
Composite Key formation for a date range in Hyperledger Fabric V1.0
问题
关于这个问题的参考,我也有一个疑问。
假设我的复合键由字段Owner_id~dateOfcreation
组成,我的键如下:
- Owner1~11-05-2017
- Owner1~12-05-2017
- Owner1~13-05-2017
- ...
- ...
- Owner1~30-05-2017
我能否通过**日期范围
**(例如Owner1~12-05-2017
到Owner~27-05-2017
)来获取状态?
根据我的理解,stub.GetStateByRange(startKey,endKey)
将返回按字典顺序排列的键,因此它不会返回预期的范围。如果我理解有误,请纠正我。
我尝试重新排列键,如下所示:
- 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"})
,它将返回以这个范围开头的所有键。这样正确吗?
但是,即使在这种情况下,我也无法获得我想要的**日期范围
**的确切输出。
有人能否建议我正确实现这个功能的方法。我认为在资产共享的背景下,这是一个常见的业务场景,请帮忙。
提前感谢
英文:
With reference to this question, I also have a doubt.
<br/> Suppose my composite key is formed with the fields Owner_id~dateOfcreation
and my keys are like:
> - Owner1~11-05-2017
> - Owner1~12-05-2017
> - Owner1~13-05-2017
> - ...
> - ...
> - Owner1~30-05-2017
Will it be possible for me to get states for a date range
for example Owner1~12-05-2017 to Owner~27-05-2017
?
In my understanding stub.GetStateByRange(startKey,endKey)
will return the keys which are in lexical order, so it will not return the expected range.
Correct me if I am wrong.
I tried to re-arrange the keys like:
> - Owner1~2017_05_11
> - Owner1~2017_05_12
> - Owner1~2017_05_13
> - ...
> - ...
> - Owner1~2017_05_30
In this case if i use
<br/>stub.GetStateByPartialCompositeKey('owner~year~month~day',[]string{"owner1","2017","05"})
it will return all the keys starting with these range. is it correct?
But here also I am not getting my exact output for a date range
.
Can anyone suggest me the proper way to implement this. I think it is a common business scenario in the context of asset sharing, so please help.
Thanks in advance
答案1
得分: 1
在重新阅读您的问题和评论后,我认为您已经有了自己的解决方案。使用GetStateByRange函数怎么样?该函数不返回键,而是返回一个带有值的迭代器。
根据您在最后一条评论中的说法,我想列出在日期范围内创建的所有资产,我将如何从账本中查询它。所以,如果我是您,我会使用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())
}
您应该在函数调用中传递您的**日期范围
**值,放在args中。
英文:
After rereading your question and the comments, I think that you have your own solution for you. What about using the function GetStateByRange? This function doesn't return keys, it returns an iterator with the values.
As you said in your last comment, I want to list the all assets created with in a date range how I will query it from ledger. So, if I were you, I'd use the GetStateByRange function, passing to it the date range.
Here I paste you an example of a function that I used.
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())
}
You should pass your date range
values in the function call, in the args.
答案2
得分: 1
根据现有的评论、采用的解决方案和API规范,可以得出结论:stub.GetStateByPartialCompositeKey
是最适合这个需求的API。
要仅获取一天的数据,可以使用json的丰富查询date_field:value
,如果它使用的是CouchDB作为其状态数据库的话。由于这不是一个提交事务,所以在这里使用丰富查询没有问题。
英文:
As with the existing comments, adopted solutions and API specification, it is concluded that stub.GetStateByPartialCompositeKey
is best suited API for this requirement.
<br/>To fetch data only for a day, it can use rich query with json date_field:value
also if it is using CouchDB as its state db. Since it is not a committing transcation no issue to use rich query here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论