#join #view #couchdb
#Присоединиться #Вид #couchdb
Вопрос:
У меня проблема с «объединением» некоторых документов в представлении. Вот моя схема: Документы с типом «категория» могут содержать встроенный массив идентификаторов для документов с типом «страница». В обоих есть поле «name».
Мои документы:
{
"_id": "887c28dcf6dd8429d404d276b900b203",
"_rev": "3-c4d1e0c8378bb0081b5fe3522ee649a0",
"TYPE": "category",
"NAME": "Home",
"PAGES": [
{"PAGE_ID": "887c28dcf6dd8429d404d276b900ad8f"},
{"PAGE_ID": "887c28dcf6dd8429d404d276b900b203"},
{"PAGE_ID": "887c28dcf6dd8429d404d276b900bae0"}
]
}
{
"_id": "887c28dcf6dd8429d404d276b9008c01",
"_rev": "1-afd54c654ae5afa56a3fbd7b1ba119d2",
"TYPE": "page",
"NAME": "Foo"
}
Теперь я хочу объединить их в представлении с помощью этой функции map:
function(doc) {
if (doc.TYPE == "category") {
for (id in doc.PAGES) {
emit(doc.NAME, doc.PAGES[id].PAGE_ID);
}
}
}
Но вместо PAGE_ID я хочу ИМЯ документа, на который ссылается.
По сути, это пример из CouchDB wiki, но они не показывают функцию map. Итак, есть идеи?
Ответ №1:
Вам нужно включить _id
поле где-нибудь в ваше выходное значение. После этого вы используете include_docs=true
, и представление будет включать связанный документ вместо исходного документа. Например:
function(doc) {
if (doc.TYPE == "category") {
for (var x = 0; x < doc.PAGES.length; x ) {
emit(doc.NAME, { _id: doc.PAGES[x].PAGE_ID });
}
}
}
Когда вы запрашиваете это представление, вы добавляете include_docs=true
к своему URL. И ваш вывод view добавит новое поле к каждой вызываемой строке doc
. Обычно это поле будет содержать полный исходный документ. В этом случае он будет включать связанный документ, на который вы ссылаетесь.
РЕДАКТИРОВАТЬ Кстати, вы неправильно используете for...in
цикл. for...in
Используется для перебора свойств объекта. Вам нужно использовать простой for
цикл для повторения массива, подобного этому.
Комментарии:
1. Привет, теперь я получаю странный результат: первая страница списка разрешается, затем я получаю две категории с неразрешенными идентификаторами страниц, а затем четвертую страницу (снова разрешается). Но у меня есть две категории (первая содержит три страницы, вторая только одну) и четыре страницы.
2. Я не мог не заметить, что ваш 2-й
PAGE_ID
совпадает с_id
для самого документа. О, и я только что заметил, что ваш JS неверен… (следите за изменениями в моем ответе)3. О, я допустил глупую ошибку copy’n’paste с идентификаторами, извините за это. Теперь это работает, спасибо!
4. Также рассмотрите возможность включения
_rev
поля, чтобы при?include_docs=true
получении вы получали фактический документ, соответствующий этому выводу карты. (Или, если вы не используете include_docs, у вас все еще есть редакция, чтобы вы могли обновить документ без его повторной выборки.)