2010-07-15 3 views
4

Я довольно новыми для CouchDB, и я до сих пор есть некоторые проблемы, обертывание мою голову вокруг всего MapReduce пути запрашивая мои данные ...связанных граф документов в CouchDB

Чтобы остаться с традиционным «Блог» Например, скажем, у меня есть 2 вида документов: post и comment ... каждый комментарий документ имеет post_id поля ...

есть ли способ я могу получить список сообщений с количеством замечаний по каждому из этих сообщений с одним запросом? Скажем, я хочу, чтобы отобразить список заголовков с количеством комментариев для каждого пост, как это:

My First Post: 4 comments 
My Second Post: 6 comments 
.... 

Я знаю, что может сделать следующее:

function(doc) { 
    if(doc.type == "comment") { 
     emit(doc.post_id, 1); 
    } 
} 

, а затем уменьшить его, как это :

function (key, values, rereduce) { 
    return sum(values); 
} 

который дает мне список каждого идентификатора блога с количеством комментариев для каждой записи. Но тогда мне нужно получать заголовки сообщений в блогах отдельно, так как единственное, что у меня есть сейчас, это их идентификатор ...

Итак, есть ли способ получить список всех заголовков блога с указанием количества комментарии для каждого сообщения, выполнив только 1 запрос?

ответ

0

Мой опыт показывает, что в большинстве «нормальных» случаях лучше иметь один большой документ, содержащий как пост и комментарии.

Конечно, я знаю, что это не очень хорошая идея, если у вас есть тысячи комментариев. Вот почему я сказал «самые нормальные случаи». Не выбрасывайте эту опцию сразу, как «неправильную».

Вы получаете всевозможные лакомства, такие как возможность подсчета количества комментариев на карте, простой (один запрос) поиск всей страницы из базы данных, ACID за сообщение (с комментариями) и т. Д. Кроме того, Мне нужно подумать об обманах, таких как сопоставление вида прямо сейчас.

Если это происходит медленно, вы можете впоследствии преобразовать свою структуру данных (черт возьми, мы делали это каждый день с помощью РСУБД).

Если ваш прецедент не подходит для этого, я настоятельно рекомендую вам попробовать его. Он работает замечательно хорошо.

+0

Я думаю, что основным недостатком, который мы рассмотрим здесь, будет более медленное обновление, так как вам нужно извлечь большой документ, добавить комментарий и отправить все обратно, а затем проверить конфликты и, возможно, начать все, если они есть. –

0

Вы могли бы сделать что-то вроде этого:

function(doc) { 
    if(doc.type == "post") { 
     emit([doc._id, 'title', doc.title], 0); 
    } 
    if(doc.type == "comment") { 
     emit([doc.post_id, 'comments'], 1); 
    } 
} 

Тогда вы получите представление, где каждый пост получает две строки, одна с названием и один с комментариями.

Вы можете объединить строки вместе на клиенте, или вы можете использовать функцию «список», чтобы объединить эти группы строк вместе в CouchDB:

http://wiki.apache.org/couchdb/Formatting_with_Show_and_List

function list(head, req) { 
    var post; 
    var row; 
    var outputRow = function() { 
    if(post) { send(post); } 
    } 
    while(row = getRow()) { 
    if(!post || row.key[0] != post.id) { 
     outputRow(); 
     post = {id:row.key[0]}; 
    } 
    /* If key is a triple, use part 3 as the value, otherwise assume its a count */ 
    var value = row.key.length === 3 ? row.key[2] : row.value; 
    post[row.key[1]] = value; 
    } 
    outputRow(); 
} 

Примечание: не протестированного кода !

Смежные вопросы