В приведенном выше примере, чтобы получить все дочерние элементы для идентификатора документа, ваша функция карты будет выглядеть примерно так:
function (doc) {
if (doc.parent) {
emit(doc.parent, { "_id": doc._id });
}
}
(Свойство "child", имеющееся в документе 2даже не нужно.)
Учитывая данные вашего примера, это будет выдаваться дважды:
[ "1", { "_id": "2" } ]
[ "2", { "_id": "3" } ]
Чтобы получить дочерние идентификаторы для одного родителя, вы должны получить доступ к представлению следующим образом:
http://.../db/_design/viewName/_view/childfunc?key="2"
Чтобы получить полный документ, добавьте параметр include_docs в строку запроса.
Если вы хотите получить родительский и дочерний элементы одновременно, ваша функция карты тольконемного по-другому:
function (doc) {
emit([ doc._id, "" ], { "_id": doc.id });
if (doc.parent) {
emit([ doc.parent, doc._id ], { "_id": doc.id })
}
}
Эта функция может выдавать дважды, поэтому в итоге вы получите следующее:
[ [ "1", "" ], { "_id": "1" } ]
[ [ "1", "2" ], { "_id": "2" } ]
[ [ "2", "" ], { "_id": "2" } ]
[ [ "2", "3" ], { "_id": "3" } ]
[ [ "3", "" ], { "_id": "3" } ]
Благодаря сортировке сортировки, родители заканчивают в первую очередь (так как ихвторой ключевой элемент - это ""), и потомки заканчиваются потом.Вам не нужно использовать child _id в качестве второго ключевого элемента, вы можете использовать любое естественное свойство сортировки, которое будет наиболее целесообразным.(Дата создания, имя, название, что угодно.)
Если у вас не было свойства child, вы могли бы сделать функцию Reduce для получения всех потомков родителя:
function (key, vals) {
var children = [];
for (var docId in vals) {
if (key[1] !== "") {
children.push(docId);
}
}
return children;
}
Эта функция проверяет, не является ли дочерняя часть ключа пустой, и если это так, она помещает идентификатор документа в массив.Таким образом он перебирает все значения и возвращает массив после завершения.