CouchDB: совместные виды и клавиши
На моем диване у меня есть такие пары документов:
{
_id: "DOCID",
type: "Task",
info: { k1: "v1", k2: "v2" }
}
{
_id: "ANOTHER DOCID",
type: "Final",
task: "DOCID",
author: "Authorname"
}
Для автора может существовать несколько таких пар.
Теперь мне нужно представление, которое даст мне информацию, связанную таким образом, что author
сопровождается info
,
Используя словосочетание, я создал следующий вид:
function(doc) {
if (doc.doc_type == "Final")
emit([doc.task, 0], doc.author);
if (doc.doc_type == "Task")
emit([doc._id, 1], doc.definition);
}
И я получаю такие результаты:
["153b46415108e95c811e1d4cd018624f", 0] -> "Authorname"
["153b46415108e95c811e1d4cd018624f", 1] -> { info here }
Во-первых, я использовал функцию Reduce, чтобы объединить обе функции в одну, но после синхронизации их локальная группировка выполняется намного быстрее.
Однако, так оно и есть сейчас, я не могу запросить это представление по "имени автора". Особенно не потому, что info
не приходит с именем автора.
Я думаю, что есть некоторые решения:
- Используйте функцию сокращения с группировкой и манипулируйте ключом, чтобы он показывал автора (я даже не знаю, возможно ли манипулирование сгруппированным ключом)
- Получить все строки, сгруппировать их локально и отфильтровать по автору, которого я ищу (вероятно, слишком много нежелательных накладных расходов)
- Есть несколько просмотров и выполнить 2 запроса. Один, чтобы получить DOCID, а затем запросить DOCID.
- Умно запрашивайте совместное представление: включите Authorname в ключ и тип запроса, что эффективно, но я также не думаю, что это возможно, так как запрос Authorname исключит фактический
info
,
Так что бы вы посоветовали продолжить? И да, есть причина, почему информация является отдельной (несколько Final
документы могут быть связаны с тем же Task
документ, следовательно, имеющий ту же информацию)
Лучший
Редактировать Предоставленное решение действительно отвечает на мой вопрос, но я решил использовать свое представление и сгруппировать результаты в своем коде (представление Django), которое оказалось очень быстрым!
1 ответ
Теперь мне нужно представление, которое даст мне информацию, связанную таким образом, что автор сопровождается информацией.
Так что, если я правильно понимаю, требования
Вид должен запрашиваться по имени автора.
Результатом вывода должны быть имя автора и
INFO
документ.
Ну, ваши документы идеально структурированы для поддержки поиска связанных документов
Я думаю, что эта функция карты должна сделать это
function(doc) {
if(doc.author){
emit(doc.author,{_id:doc.task});
}
если я сделаю запрос с include_docs=true
вот результат, который я получаю
{
total_rows: 1,
offset: 0,
rows: [
{
id: "19ae88d060834dafdea9417384e2db20",
key: "Authorname",
value: { _id: "DOCID" },
doc: {
_id: "DOCID",
_rev: "1-d7fe42dd7858238bb2d1112abf24f046",
type: "Task",
info: { k1: "v1", k2: "v2" }
}
}
]
}
О сокращении от couchdb вики
Функция уменьшения должна уменьшить входные значения до меньшего выходного значения. Если вы строите составную структуру возврата в своем редукте или просто трансформируете поле значений, а не суммируете его, возможно, вы неправильно используете эту функцию
Редактировать на основе комментария:-
Поскольку документ задания слишком большой и вы не хотите его извлекать, есть два подхода, которые вы можете использовать
Вставить информацию прямо в автора. Поскольку все, что вы хотите от задачи, это информационная часть. Couchdb и другие базы данных no sql способствуют нормализации данных для облегчения доступа.
Используйте функцию list, чтобы преобразовать большой вывод json в формат, который вы сможете использовать.