【问题标题】:CouchDB indexes to connect the dots between documentsCouchDB 索引以连接文档之间的点
【发布时间】:2021-05-26 02:44:46
【问题描述】:

我有以下文件:

{ _id: "123", type: "project", worksite_id: "worksite_1" }
{ _id: "456", type: "document", project_id: "123" }
{ _id: "789", type: "signature", document_id: "456" }

我的目标是运行查询并不可避免地对与worksite_id: worksite_1 有连接的所有文档进行过滤复制。

例子:

  1. 因为这个项目有我要找的工地
  2. 文档有那个项目
  3. 签名有那个文件

如果我想要该工作场所的所有内容,我应该能够检索所有这些文档。

通常我会在我的type:documenttype:signature 中添加一个worksite_id。但是,由于各种原因,项目中的工地可能会发生变化。

我想知道是否有办法创建索引或做一些我没想过的事情来显示这些相似之处。

This 感觉它走在正确的道路上,但解释将文档放在其他文档中,我只是希望它们分开。

【问题讨论】:

  • 你考虑过relational-pouch吗?
  • @MartinBramwell 我相信我需要创建一个视图/过滤器才能完成我需要做的复制

标签: couchdb pouchdb cloudant couchdb-2.0 couchdb-mango


【解决方案1】:

地图函数一次只考虑一个文档,因此除非该文档知道其他文档,否则您无法将它们链接在一起。您的结构意味着 SQL 术语中的三表连接。

对于您的结构,您所能期望的最好结果是两个请求的解决方案。您可以创建一个仅显示已签名文档的视图:

function (doc) {
  if (doc && doc.type && doc.type === "signature" && doc.document_id) {
    emit(doc.document_id, {_id: doc.document_id})
  }
}

并使用相同的技术,将项目链接到文档 - 但您无法将所有三个链接都链接起来。

【讨论】:

    【解决方案2】:

    我想我有你要找的东西。

    这是一些数据:

    {
      "docs": [
        {
            "_id": "123",
            "type": "project",
            "code": "p001"
        },
        {
            "_id": "1234",
            "type": "worksitelog",
            "documents": [
              {
                "timestamp": "20180921091501",
                "project_id": "123",
                "document_id": "457",
                "signature_id": "789"
              },
              {
                "timestamp": "20180921091502",
                "project_id": "123",
                "document_id": "457",
                "signature_id": "791"
              },
              {
                "timestamp": "20180921091502",
                "project_id": "123",
                "document_id": "458",
                "signature_id": "791"
              },
              {
                "timestamp": "20180921091502",
                "project_id": "123",
                "document_id": "456",
                "signature_id": "790"
              }
            ],
            "worksite_id": "worksite_2"
        },
        {
            "_id": "1235",
            "type": "worksitelog",
            "documents": [
              {
                "timestamp": "20180913101502",
                "project_id": "125",
                "document_id": "459",
                "signature_id": "790"
              }
            ],
            "worksite_id": "worksite_1"
        },
        {
            "_id": "124",
            "type": "project",
            "code": "p002"
        },
        {
            "_id": "125",
            "type": "project",
            "code": "p003"
        },
        {
            "_id": "456",
            "type": "document",
            "code": "d001",
            "project_id": "123",
            "worksite_id": "worksite_2"
        },
        {
            "_id": "457",
            "type": "document",
            "code": "d002",
            "project_id": "123",
            "worksite_id": "worksite_2"
        },
        {
            "_id": "458",
            "type": "document",
            "code": "d003",
            "project_id": "123",
            "worksite_id": "worksite_2"
        },
        {
            "_id": "459",
            "type": "document",
            "code": "d001",
            "project_id": "125",
            "worksite_id": "worksite_1"
        },
        {
            "_id": "789",
            "type": "signature",
            "user": "alice",
            "pubkey": "65ab64c64ed64ef41a1bvc7d1b",
            "code": "s001"
        },
        {
            "_id": "790",
            "type": "signature",
            "user": "carol",
            "pubkey": "tlmg90834kmn90845kjndf98734",
            "code": "s002"
        },
        {
            "_id": "791",
            "type": "signature",
            "user": "bob",
            "pubkey": "asdf654asdf6854awer654awer654eqr654wra6354f",
            "code": "s003"
        },
        {
            "_id": "_design/projDocs",
            "views": {
              "docsPerWorkSite": {
                "map": "function (doc) {\n  if (doc.type && ['worksitelog', 'document', 'project', 'signature'].indexOf(doc.type) > -1) {\n    if (doc.type == 'worksitelog') {\n      emit([doc.worksite_id, 0], null);\n      for (var i in doc.documents) {\n        emit([doc.worksite_id, Number(i)+1, 'p'], {_id: doc.documents[i].project_id});\n        emit([doc.worksite_id, Number(i)+1, 'd'], {_id: doc.documents[i].document_id});\n        emit([doc.worksite_id, Number(i)+1, 's'], {_id: doc.documents[i].signature_id});\n      }\n    }\n  }\n}"
              }
            },
            "language": "javascript"
        }
      ]
    }
    

    将该数据作为stackoverflow_53752001.json保存到磁盘。

    使用 Fauxton 创建一个名为 stackoverflow_53752001 的数据库。

    这是一个 bash 脚本,用于从文件 stackoverflow_53752001.json into the databasestackoverflow_53752001` 加载数据。显然,您需要编辑前三个参数。修复它,然后将其粘贴到(Unix)终端窗口中:

    USRID="you";
    USRPWD="yourpwd";
    HOST="yourdb.yourpublic.work";
    
    COUCH_DATABASE="stackoverflow_53752001";
    FILE="stackoverflow_53752001.json";
    #
    COUCH_URL="https://${USRID}:${USRPWD}@${HOST}";
    FULL_URL="${COUCH_URL}/${COUCH_DATABASE}";
    curl -H 'Content-type: application/json' -X POST "${FULL_URL}/_bulk_docs"  -d @${FILE};
    

    在 Fauxton 中,选择数据库 stackoverflow_53752001,然后在左侧菜单中选择“Design Documents”>>“projDocs”>>“Views”>>“docsPerWorkSite”。

    你会看到这样的数据:

    {"total_rows":17,"offset":0,"rows":[
      {"id":"1235","key":["worksite_1",0],"value":null},
      {"id":"1235","key":["worksite_1",1,"d"],"value":{"_id":"459"}},
              :                     :
              :                     :
      {"id":"1234","key":["worksite_2",4,"p"],"value":{"_id":"123"}},
      {"id":"1234","key":["worksite_2",4,"s"],"value":{"_id":"790"}}
    ]}
    

    如果您随后单击右上角的“选项”按钮,您将获得用于修改原始查询的选项表。选择:

    • “包含文档”
    • “键之间”
      • “开始键”:[“worksite_1”,0]
      • “结束键”:[“worksite_1”,9999]

    点击“运行查询”,您应该会看到:

    {"total_rows":17,"offset":0,"rows":[
      {"id":"1235","key":["worksite_1",0],"value":null,"doc":{"_id":"1235","_rev":"1-de2b919591c70f643ce1005c18da1c54","type":"worksitelog","documents":[{"timestamp":"20180913101502","project_id":"125","document_id":"459","signature_id":"790"}],"worksite_id":"worksite_1"}},
      {"id":"1235","key":["worksite_1",1,"d"],"value":{"_id":"459"},"doc":{"_id":"459","_rev":"1-5422628e475bab0c14e5722a1340f561","type":"document","code":"d001","project_id":"125","worksite_id":"worksite_1"}},
      {"id":"1235","key":["worksite_1",1,"p"],"value":{"_id":"125"},"doc":{"_id":"125","_rev":"1-312dd8a9dd432168d8608b7cd9eb92cd","type":"project","code":"p003"}},
      {"id":"1235","key":["worksite_1",1,"s"],"value":{"_id":"790"},"doc":{"_id":"790","_rev":"1-be018df4ecdf2e6add68a2758b9bd12a","type":"signature","user":"carol","pubkey":"tlmg90834kmn90845kjndf98734","code":"s002"}}
    ]}
    

    如果您随后将开始键和结束键更改为 ["worksite_2", 0]["worksite_2", 9999],您将看到第二个工作地点的数据。

    为此,每次您将新文档和签名写入数据库时​​,您需要:

    1. 准备一个对象{ "timestamp": "20180921091502", "project_id": "123", "document_id": "457", "signature_id": "791" }
    2. 获取对应的工地日志记录
    3. 将对象附加到documents 数组中
    4. 放回修改后的工地日志记录

    我假设每个文档有多个签名,因此您必须为每个文档写一个日志记录。如果它变得太大,您可以将worksite_id 更改为worksite_1_201812 之类的东西,我认为这将在不破坏查询逻辑的情况下每月为每个工作站点提供一个日志。

    【讨论】:

      猜你喜欢
      • 2022-01-13
      • 1970-01-01
      • 2015-03-30
      • 1970-01-01
      • 2012-01-05
      • 1970-01-01
      • 1970-01-01
      • 2013-07-15
      • 1970-01-01
      相关资源
      最近更新 更多