I have just finished the book "couchdb: a definitive guide" and started to play with design documents. there is however one thing, that I do not understand. All the examples I have seen so far are somewhat linear.
Example:
{
"_id": "1",
"_rev": ".....",
"name": "first",
"something": "blue",
"child": "2"
}
{
"_id": "2",
"_rev": ".....",
"name": "second",
"something": "green",
"child": "3"
"parent" : "1"
}
{
"_id": "3",
"_rev": ".....",
"name": "second",
"something": "red",
"parent" : "2";
}
Run Code Online (Sandbox Code Playgroud)
I have no problem writing a view, which returns all colors:
function(doc) {
if (doc.something) {
emit(doc.something,doc._id);
}
}
Run Code Online (Sandbox Code Playgroud)
But what if I want to know all (!) descendants (not children, sorry my mistake) for the element with the _id = 1 ("something": "blue")? My programming experience tells me, that i should use recursion, but I do not know how. How can I call another view function, from a view function?
In general: this problem arises, when you design a database with references between the json documents. More specifically with a transitive relationship between the elements.
Edit: For the example: I only know _id=1 and the result should be something like [_id=2, _id=3], because 2 is a child of 1 and 3 is a child of 2.
如果可能的话,不要以这种方式定义文档层次结构 - 你将在每一步都与CouchDB作斗争.
您无法在视图中真正执行层次结构遍历.视图用于独立地传输每个文档(映射)并从中生成一些聚合值(减少).
您可以使用列表同时对多个文档进行操作,但这也不是一个好的解决方案.
如果你需要保留这个数据结构(指向父/子的链接),我建议你从CouchDB外部组装结构:获取父文件,获取子文件,获取子文件等.
但是,在CouchDB中存储树的首选方法是让每个节点记住它在树中的路径:
{
"_id": "1",
"name": "first",
"something": "blue",
"path": [1]
}
{
"_id": "2",
"name": "second",
"something": "green",
"path": [1,2]
}
{
"_id": "3",
"name": "second",
"something": "red",
"path": [1,2,3]
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用此视图来获取文档的后代:
function(doc) {
for (var i in doc.path) {
emit([doc.path[i], doc.path], doc)
}
}
Run Code Online (Sandbox Code Playgroud)
要获得_id1的后代,您可以运行此查询:
http://c.com/db/_design/colors/_view/descendants?startkey=[1]&endkey=[1,{}]
Run Code Online (Sandbox Code Playgroud)
但是,存储完整路径也有其自身的缺点.我建议你在树上查看这个CouchDB维基页面.Paul Bonser撰写的这篇博客文章的来源.