从CouchDB检索层次结构/嵌套数据

问题描述

|| 我对CouchDB还是一个新手,甚至在阅读之后(现在已删除的最新存档)http://wiki.apache.org/couchdb/How_to_store_hierarchical_data(通过“将每个节点的完整路径作为属性存储在该节点中\”文档”),它仍然没有点击。 我希望不像Wiki中所述那样使用完整路径模式,而是希望将子级作为UUID的数组并将父级作为单个UUID进行跟踪。我倾向于这种模式,因此我可以通过子元素在子元素数组中的位置来保持子元素的顺序。 这是沙发上的一些示例文档,桶可以包含桶和物品,物品只能包含其他物品。 (为清楚起见,UUID缩写):
{_id: 3944
 name: \"top level bucket with two items\"
 type: \"bucket\",parent: null
 children: [8989,4839]
}
{_id: 8989
 name: \"second level item with no sub items\"
 type: \"item\"
 parent: 3944
}
{
 _id: 4839
 name: \"second level bucket with one item\"
 type: \"bucket\",parent: 3944
 children: [5694]
}
{
 _id: 5694
 name: \"third level item (has one sub item)\"
 type: \"item\",parent: 4839,children: [5390]
}
{
 _id: 5390
 name: \"fourth level item\"
 type: \"item\"
 parent: 5694
}
是否可以通过map函数中的嵌入式文档ID查找文档?
function(doc) {
    if(doc.type == \"bucket\" || doc.type == \"item\")
        emit(doc,null); // still working on my key value output structure
        if(doc.children) {
            for(var i in doc.children) {
                // can i look up a document here using ids from the children array?
                doc.children[i]; // psuedo code
                emit(); // the retrieved document would be emitted here
            }
        }
     }
}   
在理想情况下,最终的JSON输出看起来像。
{\"_id\":3944,\"name\":\"top level bucket with two items\",\"type\":\"bucket\",\"parent\":\"\",\"children\":[
     {\"_id\":8989,\"name\":\"second level item with no sub items\",\"type\":\"item\",\"parent\":3944},{\"_id\": 4839,\"name\":\"second level bucket with one item\",\"parent\":3944,\"children\":[
         {\"_id\":5694\",\"name\":\"third level item (has one sub item)\",\"parent\": 4839,\"children\":[
             {\"_id\":5390,\"name\":\"fourth level item\",\"parent\":5694}
         ]}
     ]}
 ]
}
    

解决方法

您可以在CouchDB Wiki上找到常规讨论。 我现在没有时间对其进行测试,但是您的map函数应该类似于:
function(doc) {
    if (doc.type === \"bucket\" || doc.type === \"item\")
        emit([ doc._id,-1 ],1);
        if (doc.children) {
            for (var i = 0,child_id; child_id = doc.children[i]; ++i) {
                emit([ doc._id,i ],{ _id: child_id });
            }
        }
    }
}
您应该使用
include_docs=true
查询它以获得文档,如CouchDB文档中所述:如果您的map函数发出一个具有
{\'_id\': XXX}
的对象值并且您使用
include_docs=true
参数查询视图,则CouchDB将获取ID为XXX的文档,而不是文档经过处理以发出键/值对。 添加ѭ7只能获得ID为“ 3944”的文档及其子级。 编辑:更多细节请看这个问题。     ,您可以从视图输出树形结构吗?不可以。CouchDB视图查询返回一个值列表,除了列表之外,没有其他方法可以输出这些值。因此,您必须处理地图以返回给定存储桶的所有后代的列表。 但是,您可以在视图本身后面插入一个“ 8”后处理功能,以将该列表转回嵌套结构。如果您的值知道其父级的
_id
,这是可能的-该算法相当简单,请问另一个问题是否给您带来麻烦。 您可以通过地图功能中的ID来抓取文档吗?否。无法通过CouchDB中的标识符来获取文档。该请求必须来自应用程序,其形式为文档标识符上的标准“ 10”或在查看请求中添加“ 4”。 技术原因很简单:CouchDB仅在文档更改时运行map函数。如果允许文档
A
提取文档
B
,则当
B
更改时,发出的数据将变得无效。 您可以输出所有后代而不存储每个节点的父级列表吗?不能。CouchDB映射函数为数据库中的每个文档发出一组键-值-id对,因此必须基于单个文档确定键和id之间的对应关系。 如果您有一个四层树结构
A -> B -> C -> D
,但是只让一个节点知道其父级和子级,那么上面的节点都不知道
D
A
的后代,因此您将无法使用以下方法发出
D
的id基于
A
的键,因此在输出中不可见。 因此,您有三个选择: 仅获取三个级别(之所以可能是因为
B
知道
C
A
的后代),然后通过再次运行查询来获取其他级别。 以某种方式存储节点内每个节点的后代列表(这很昂贵)。 存储节点内每个节点的父级列表。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...