Nosql CouchDB过滤器和带有视图和列表的分页
我们正在尝试用CouchDB和Golang在HL Fabric中构建一个应用程序,它的增长有点太大了,现在我们有很多数据类型,需要在数据库中创建连接等价物来过滤和显示数据 我们的尝试: 使用Mango查询按代码加入链码(这似乎不是一个好的解决方案,但它是唯一一个真正有效的解决方案) 这就是,获取父对象,循环获取子对象的结果(如果只是列出) 在过滤的情况下,事情变得更加复杂,因为我们需要按组过滤子项,获取parentID,在另一个查询中使用那些我们想要避免的带有可怕“$或”的ID 使用视图和列表加入CouchDB 所以,我们提出了这个“解决方案”,但它有很多问题Nosql CouchDB过滤器和带有视图和列表的分页,nosql,couchdb,hyperledger-fabric,Nosql,Couchdb,Hyperledger Fabric,我们正在尝试用CouchDB和Golang在HL Fabric中构建一个应用程序,它的增长有点太大了,现在我们有很多数据类型,需要在数据库中创建连接等价物来过滤和显示数据 我们的尝试: 使用Mango查询按代码加入链码(这似乎不是一个好的解决方案,但它是唯一一个真正有效的解决方案) 这就是,获取父对象,循环获取子对象的结果(如果只是列出) 在过滤的情况下,事情变得更加复杂,因为我们需要按组过滤子项,获取parentID,在另一个查询中使用那些我们想要避免的带有可怕“$或”的ID 使用视图和列表加
// Collaborator document
{
"_id": "john.doe@email.com",
"_rev": "33-0a7f4e6f6c4a60d6ffded693ed794cb6",
"docType": "collaborator",
"id": "john.doe@email.com",
"levelID": "1@level", // this is what we want to filter events by (1@level, 2@level, ...)
"name": "John",
"surname": "Doe",
"~version": "CgQCAsIA"
}
// Event document
{
"_id": "0160ca22-6ffb-40d8-a8ad-e13ce5f0a0ef",
"_rev": "1-a23a010bcadf8b7969fb7a5aba93456a",
"creation": "2021-04-14T14:29:34-0300",
"docType": "event",
"id": "0160ca22-6ffb-40d8-a8ad-e13ce5f0a0ef",
"movement": "transfer", // we want to filter events by this field also
"from": "jane.doe@email.com",
"to": "john.doe@email.com", // link to collaborator document
"quantity": 10,
"~version": "CgQCAk4A"
}
// Our view function
function (doc) {
if (doc.docType == "event"){
emit([doc.creation,doc.id] , {_id: doc.id});
emit([doc.creation,doc.id] , {_id: doc.to});
}
}
// Our list function
function (head, req) {
var row, last_key;
var event, to;
var key;
var query = {};
query.movement = req.query.movement;
query.levelID = req.query.levelID;
send('{"records" : [');
while ((row = getRow())) {
key = row.key[row.key.length-1];
if (last_key != key) {
if (last_key != "undefined") {
sendJSON();
event = undefined;
to = undefined;
}
last_key = key;
}
if (row.doc) {
if (row.doc.docType == "event") {
event = row.doc;
} else if (row.doc.docType == "collaborator"){
to = row.doc;
}
}
}
sendJSON();
send(toJSON({}));
send("]}");
function sendJSON() {
var pass = true;
if (event && to) {
if (query.movement && event.movement != query.movement) {
pass = false;
}
if (query.levelID && to.levelID != query.levelID) {
pass = false;
}
if (pass) {
event.to = to;
}
} else {
pass = false;
}
if (pass) {
send(toJSON(event));
send(",");
}
}
};
// Then we call it with
http://127.0.0.1:5984/testchannel_huenei/_design/new_design/_list/result/events
?include_docs=true&levelID=1@level&movement=transfer
&startkey=["3000-01-01T24:00:00-0300",{}]&endkey=["1999-01-01T00:00:00-0300"]&descending=true
// And the result is something like this
{
"records": [{
"_id": "0160ca22-6ffb-40d8-a8ad-e13ce5f0a0ef",
"_rev": "1-a23a010bcadf8b7969fb7a5aba93456a",
"creation": "2021-04-14T14:29:34-0300",
"docType": "event",
"id": "0160ca22-6ffb-40d8-a8ad-e13ce5f0a0ef",
"movement": "transfer"
"from": "jane.doe@email.com",
"to": {
"_id": "john.doe@email.com",
"_rev": "33-0a7f4e6f6c4a60d6ffded693ed794cb6",
"docType": "collaborator",
"id": "john.doe@email.com",
"levelID": "1@level",
"name": "John",
"surname": "Doe",
"~version": "CgQCAsIA"
},
"quantity": 10,
"~version": "CgQCAk4A"
},
{}
]
}
它可以工作,但似乎太复杂了,当使用SQL时,它是通过一个简单的连接/查询来解决的。深度嵌套文档呢
我们知道“移动”可以在url中过滤,但实际上我们还有许多其他字段要过滤,正如我们所读到的,键必须按顺序排列。
这意味着,如果我有emit([doc.to,doc.movement,doc.id],null),我需要首先指定“to”,即&startkey=[???,“transfer”]&endkey=[???,“transfer”,{}]
我们尝试了&startkey=[null,“transfer”]&endkey=[\ufff0,“transfer”,{}]
,但没有成功
但在任何情况下,按嵌套文档进行过滤都是最有问题的
还有一个主要问题是,我们无法对结果进行分页,因为关键字“limit”仅在视图中有效,而在列表中无效
在真实的Hyperledger结构世界场景中,人们如何解决这些问题?甚至在一个简单的CouchDB场景中
谢谢
emit([doc.active,doc.id],{u id:doc.id})代码>是不必要的膨胀,因为doc.id==doc.\u id?我遗漏了什么?@RamblinRose如果我理解正确,通过在URL中声明{u id:doc.id}并设置include_docs=true,CouchDB带来了该id的文档,确实需要更多信息。如上所述,父文档与子文档具有一对一的关系。这使我对list
函数和doc.id==doc.\u id
都感到困惑。“一小部分实际文件会有所帮助。”兰布林罗斯一世用更现实的例子编辑了这个问题