我正在使用createCompsiteKey
,而getSateByRange
仅返回{"done":true}
。
我尝试用concat密钥部分替换createCompsiteKey
来制作密钥,如下所示。
getSateByRange
仅返回{"done":true}
,我使用的是“ fabric-shim” v1.4.0和“ fabric-contract-api” v1.4.0。 “ fabric-peer”图像为1.4.6。
addState
到db的代码如下:
class StateList {
async addState(state){
let keyParts = state.getSplitKey();
let keyPrefix = (String)(keyParts.slice(0,1));
let keyOthers = keyParts.slice(1);
/*. comment createCompositeKey
let key = this.ctx.stub.createCompositeKey(keyPrefix, keyOthers);
*/
let key = keyParts.map(part => part).join('');
let data = State.serialize(state);
await this.ctx.stub.putState(key, data);
}
}
class State {
constructor(stateClass, keyParts) {
this.class = stateClass;
this.key = State.makeKey(keyParts);
}
static makeKey(keyParts) {
return keyParts.map(part => part).join(':');
}
static splitKey(key){
return key.split(':');
}
}
async getDevCollectByRange(ctx, startKey, endKey){
let args = [];
args[0] = startKey;
args[1] = endKey;
let xiotdatadevlist = await ctx.xiotDataDevList.getDevByRange(args);
return Buffer.from(xiotdatadevlist);
}
async getAllResults(iterator){
let allResults = [];
while (true) {
const res = await iterator.next();
if (res.value && res.value.value.toString()) {
console.log(res.value.value.toString('utf8'));
const Key = res.value.key;
let Record;
try {
Record = JSON.parse(res.value.value.toString('utf8'));
} catch (err) {
console.log(err);
Record = res.value.value.toString('utf8');
}
allResults.push({ Key, Record });
}
if (res.done) {
await iterator.close();
return allResults;
}
}
}
async getObjectsByRange(args) {
if (args.length < 2) {
throw new Error('Incorrect number of arguments. Expecting 2');
}
// date
const startKey = args[0];
const endKey = args[1];
const resultsIterator = await this.ctx.stub.getStateByRange(startKey, endKey);
let results = await this.getAllResults(resultsIterator, false);
return Buffer.from(JSON.stringify(results));
}
如果我使用createCompsiteKey
,getSateByRange
如何找到我的记录?
还是织物密钥必须满足什么条件?
任何建议,谢谢。
答案 0 :(得分:0)
在Fabric的早期版本中,getStateByRange
API用于返回复合键,即使在对简单键进行范围查询时也是如此。例如,以下对marble02链码示例的范围查询返回了应该返回的简单键(例如marble2
,marble3
和组合键(例如color~namebluemarble2
,color~namebluemarble2
)仅marble2
和marble3
。
$ peer chaincode query -n mycc1 -v 0 -c {"Args":["getMarblesByRange","a","z"]} -o 127.0.0.1:7050 -C ch1
查询结果:
[
{"Key":"color~namebluemarble3", "Record":}
{"Key":"color~nameredmarble2", "Record":},
{"Key":"marble2", "Record":{"docType":"marble","name":"marble2","color":"red","size":50,"owner":"tom"}},
{"Key":"marble3", "Record":{"docType":"marble","name":"marble3","color":"blue","size":70,"owner":"tom"}}
]
Fabric无法区分简单键还是复合键,因此GetStateByRange()
只能返回简单键。
复合键具有objectType前缀。复合键的每个部分都由空字符定界,例如chaincodeid 0x00 objectType 0x00 ck1 0x00 ck2 0x00
。这种设计确保了各种组合键类型都有一个objectType命名空间,以确保不同类型之间不会发生冲突。您可以将鼠标悬停在具有复合键的任何CouchDB记录上的 copy 图标上,如下图所示。
现在,getStateByRange()
仅返回简单键,而getStateByPartialCompositeKey()
仅返回复合键。简单键和组合键的名称空间不同,以避免冲突。有关此的更多信息,您可以参考此thread,Fabric维护人员在其中讨论了如何解决此问题。
如果您在开始和结束时执行无范围查询,则结果中将看不到任何复合键。我自己尝试过,这些是我收到的结果。
peer chaincode query -n marbles -C mychannel -c '{"Args":["getMarblesByRange", "", ""]}'
输出:
[
{"Key":"azurite","Record":
{"color":"yellow","docType":"marble","name":"azurite","owner":"john","size":2}
},
{"Key":"marble1","Record":
{"color":"red","docType":"marble","name":"marble1","owner":"tom","size":50}
},
{"Key":"marble2","Record":
{"color":"blue","docType":"marble","name":"marble2","owner":"tom","size":70}
}
]
但是,当我将\u0000
用作开始键时,我也收到了包含复合键的记录。
peer chaincode query -n marbles4 -C mychannel -c '{"Args":["getMarblesByRange", "\u0000", ""]}'
输出:
[
{"Key":"\u0000color~name\u0000blue\u0000marble2\u0000","Record":"\u0000"},
{"Key":"\u0000color~name\u0000red\u0000marble1\u0000","Record":"\u0000"},
{"Key":"\u0000color~name\u0000yellow\u0000azurite\u0000","Record":"\u0000"},
{"Key":"azurite","Record":
{"color":"yellow","docType":"marble","name":"basil","owner":"john","size":2}
},
{"Key":"marble1","Record":
{"color":"red","docType":"marble","name":"marble1","owner":"tom","size":50}
},
{"Key":"marble2","Record":
{"color":"blue","docType":"marble","name":"marble2","owner":"tom","size":70}
}
]
因此,总而言之,我认为您不应该使用getStateByRange
API,而应该使用getStateByPartialCompositeKey
来获取包含复合键的记录。