Nosql CouchDB过滤器和带有视图和列表的分页

Nosql CouchDB过滤器和带有视图和列表的分页,nosql,couchdb,hyperledger-fabric,Nosql,Couchdb,Hyperledger Fabric,我们正在尝试用CouchDB和Golang在HL Fabric中构建一个应用程序,它的增长有点太大了,现在我们有很多数据类型,需要在数据库中创建连接等价物来过滤和显示数据 我们的尝试: 使用Mango查询按代码加入链码(这似乎不是一个好的解决方案,但它是唯一一个真正有效的解决方案) 这就是,获取父对象,循环获取子对象的结果(如果只是列出) 在过滤的情况下,事情变得更加复杂,因为我们需要按组过滤子项,获取parentID,在另一个查询中使用那些我们想要避免的带有可怕“$或”的ID 使用视图和列表加

我们正在尝试用CouchDB和Golang在HL Fabric中构建一个应用程序,它的增长有点太大了,现在我们有很多数据类型,需要在数据库中创建连接等价物来过滤和显示数据

我们的尝试:

使用Mango查询按代码加入链码(这似乎不是一个好的解决方案,但它是唯一一个真正有效的解决方案) 这就是,获取父对象,循环获取子对象的结果(如果只是列出)

在过滤的情况下,事情变得更加复杂,因为我们需要按组过滤子项,获取parentID,在另一个查询中使用那些我们想要避免的带有可怕“$或”的ID

使用视图和列表加入CouchDB

所以,我们提出了这个“解决方案”,但它有很多问题

  // 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
都感到困惑。“一小部分实际文件会有所帮助。”兰布林罗斯一世用更现实的例子编辑了这个问题