简体   繁体   中英

Composite Key formation for a date range in Hyperledger Fabric V1.0

With reference to this question, I also have a doubt.
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
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 :)

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.

As with the existing comments, adopted solutions and API specification, it is concluded that stub.GetStateByPartialCompositeKey is best suited API for this requirement.
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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM