如何解决从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
的后代),然后通过再次运行查询来获取其他级别。
以某种方式存储节点内每个节点的后代列表(这很昂贵)。
存储节点内每个节点的父级列表。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。