2013-04-17 3 views
1

Есть 3 CouchDB типы документов:Как связать несколько документов в одном окне

пользователя

{ "_id: "user/author1", "type: "user", "name" : "Joe Doe"} 

Обзор

{ "_id: "review/review1", "type" : "review", "content" : "..." } 

Продукт

{ "_id": "product/awesomeproduct", "type" : "product", "reviews": [ 
    { 
     "author": "author1", 
     "review_id": "review/review1" 
    }, 
    { 
     "author": "author2", 
     "review_id": "review/review2" 
    } 
    ] 
} 

Как я могу получить все данные из документов с единым представлением?

Я пытаюсь использовать связанные документы, но можно использовать (с include_docs = верно) только один на выделяют:

(coffescript)

(doc) -> 
    if doc.type is "product" 
    for review in doc.reviews 
     emit [doc._id, review.author],{_id: "user/" + review.author} 
     emit [doc._id, review.author],{_id: review.review_id} 

Но я хочу что-то вроде этого (получить пользователя и обзор документа в одиночном испускании):

(doc) -> 
    if doc.type is "product" 
    for review in doc.reviews 
     key = [doc._id, review.author] 
     value = {"user:" {_id: "user/" + review.author},"review" :{_id: review.review_id}} 
     emit key, value 

Есть ли способ, как его достичь? Как присоединиться к этим типам документов в едином представлении?

Я хочу, чтобы получить что-то вроде этого результата:

[ 
    key : ["product/awesomeproduct", "author1"], 
    value : {user: {_id: "user/author1"},review :{_id: "review/review1"}} 
    doc: 
    {user: {"_id: "user/author1", "type: "user", "name" : "Joe Doe"}, 
     review: {"_id: "review/review1", "type" : "review", "content" : "..."} 
    } 

] 
+0

Ах-ха, хорошо. Я добавил еще один ответ ниже. –

ответ

1

Короткий андерс ... вы не можете. Couchdb позволяет вам одновременно выпускать только один документ.

Существует два подхода к получению необходимых данных.

  1. Сохраните структуру как есть и выполните соединение вручную самостоятельно в своем клиентском коде.
  2. Денормализовать ваши данные. Денормализация здесь будет чем-то вроде размещения отзывов внутри вашего документа продукта.

Data modeling considerations для MongoDB, но понятия о том, как структурировать ваши данные в среде NoSQL такие же, как они для CouchDB

4

походит на классический случай для функции уменьшения (извините, не кофе для меня :)):

карта

function(doc) { 
    if(doc.type == "product") { 
     for(review_i in doc.reviews) { 
      var review = doc.reviews[review_i]; 
      emit([doc._id, review.author],{user: "user/" + review.author, review: review.review_id}); 
     } 
    } 
} 

сокращение

function(keys, values) { 
    return(values); 
} 

Результат (снижение = истина [& группа = точный]):

key          value 
["product/awesomeproduct", "author2"] [{user: "user/author2", review: "review/review1"}] 
["product/awesomeproduct", "author1"] [{user: "user/author1", review: "review/review1"}] 

Что именно вы хотите, излучаемые данные выглядеть?

Ответ на комментарий выше Должно быть возможно, за исключением того, как вы хотите отображать данные в возвращенном документе вида. include_docs означает возврат всего документа, как он есть.Похоже, вы хотели, чтобы представить данные, одинаковые с точки зрения и в возвращенном документ, поэтому, возможно, изменить структуру документа, чтобы быть:

_id : ... 
data : 
    { 
     user: {"_id: "user/author1", "type: "user", "name" : "Joe Doe"}, 
     review: {"_id: "review/review1", "type" : "review", "content" : "..."} 
    } 

В противном случае, если вы просто хотите ключ просмотра, значения для быть выше структура, а не заботиться о структуре возвращаемого Дока:

карте

function(doc) { 
    if(doc.type == "product") { 
     for(review_i in doc.reviews) { 
      var review = doc.reviews[review_i]; 
      emit([doc._id, review.author],{ 
          user: {_id: "user/" + review.author}, 
          review: {_id: review.review_id} 
          }); 
     } 
    } 
} 

что должно привести к:

curl -X GET http://localhost:5984/testdb2/_design/test/_view/test?include_docs=true\&reduce=false 

{ 
    "offset": 0, 
    "rows": [ 
     { 
      "doc": { 
       "_id": "product/awesomeproduct", 
       "_rev": "2-20f0c6cc663e03ab93f8646f09d87db2", 
       "reviews": [ 
        { 
         "author": "author1", 
         "review_id": "review/review1" 
        }, 
        { 
         "author": "author2", 
         "review_id": "review/review1" 
        } 
       ], 
       "type": "product" 
      }, 
      "id": "product/awesomeproduct", 
      "key": [ 
       "product/awesomeproduct", 
       "author1" 
      ], 
      "value": { 
       "review": { 
        "_id": "review/review1" 
       }, 
       "user": { 
        "_id": "user/author1" 
       } 
      } 
     }, 
     { 
      "doc": { 
       "_id": "product/awesomeproduct", 
       "_rev": "2-20f0c6cc663e03ab93f8646f09d87db2", 
       "reviews": [ 
        { 
         "author": "author1", 
         "review_id": "review/review1" 
        }, 
        { 
         "author": "author2", 
         "review_id": "review/review1" 
        } 
       ], 
       "type": "product" 
      }, 
      "id": "product/awesomeproduct", 
      "key": [ 
       "product/awesomeproduct", 
       "author2" 
      ], 
      "value": { 
       "review": { 
        "_id": "review/review1" 
       }, 
       "user": { 
        "_id": "user/author2" 
       } 
      } 
     } 
    ], 
    "total_rows": 2 
} 

Это не похоже, что это то, что вы искали, но это мое лучшее предположение.

+0

Функция уменьшения будет работать, но, к сожалению, она не может использоваться с ** include_docs = true **. Поэтому я не получаю эти данные из других документов. Я обновил сообщение с результатом, который мне нужен. – Svagis

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