Просмотры CouchDB: объединения и подзапросы - PullRequest
8 голосов
/ 27 ноября 2010

Я разместил это в списке рассылки CouchDB-Users, но решил, что я разыграю свою сеть немного шире.

[ссылки уничтожены из-за новых правил спама в stackoverflow :-(]

Надеюсь, один из вас умных людей может помочь (или, по крайней мере, кто-то может окончательно сказать мне, что я пытаюсь сделать, это невозможно, и мне придется искать альтернативы ... Я слышал, MySQL на подъеме (-:).

Справочная информация: я создал пример базы данных здесь: scoates-test.couchone.com/_utils/database.html?follow / scoates-test.couchone.com/follow

У меня есть два типа документов: type = user и type = asset.

Пример пользователя: scoates-test.couchone.com/_utils/document.html?follow/c988a29740241c7d20fc7974be05f67d

Пример ресурса: scoates-test.couchone.com/_utils/document.html?follow/c988a29740241c7d20fc7974be061d62

Пользователи могут подписываться на других пользователей (поле type = user document "follow"). Пример выше user (username= bob) is "следует" 2пользователи:

"following": [
   "c988a29740241c7d20fc7974be05ec54", // username=aaron
   "c988a29740241c7d20fc7974be060bb4" // username=dale
]

Активы принадлежат конкретному пользователю.Приведенный выше пример актива принадлежит c988a29740241c7d20fc7974be061d62 (username = bob).

Надеюсь, это имеет смысл.

Я хотел бы запросить ресурсы, принадлежащие пользователям, за которыми следует bob (aaron and dale)), и я не могу положить палец на просмотр кода, который позволит это.Я могу легко передать все активы, которые принадлежат c988a29740241c7d20fc7974be05f67d.

Я мог бы сделать это в двух запросах.Сначала я запросил бы у CouchDB c988a29740241c7d20fc7974be05f67d, а затем поместил в POST следующее «ключи» для представления, которое возвращает активы, принадлежащие этим ключам, но вы заметите, что в моих документах type = asset также есть поле «когда», иЯ хочу иметь возможность упорядочить таким образом, выбрав [doc.owner, doc.when] в качестве ключа, а затем используя startKey / endKey.Так что POST ключей отсутствует, я думаю.

I может просто присоединиться на стороне приложения (запросить следующие ключи, сделать один запрос для каждого из этих ключей, затем отсортировать в приложениисторона), но это очень сильно нарушает нумерацию страниц (мне нужно запросить ограничение на размер страницы для каждого следующего), и это очень быстро выходит из-под контроля (если пользователь подписывается на 1000 пользователей, это 10000 записей на странице).

Ни одно из этих решений не работает для меня.Я хотел бы сделать это в CouchDB.

Я действительно в замешательстве.Пожалуйста, помогите.

S

1 Ответ

10 голосов
/ 28 ноября 2010

Существует фундаментальное правило для представлений CouchDB, которое может помочь вам решить эту проблему.

Запрос представления CouchDB возвращает ноль, один или несколько кортежей значения ключа, так что ключ, значение и идентификатор вычисляются из одного и того же документа .При желании вы можете запросить документ с предоставленным идентификатором (который может быть, а может и не быть документом, который использовался для вычисления кортежа).

Если подумать, это вполне логично: каждый кортежявляется следствием emit(), поэтому все передаваемые данные могут поступать только из одного документа.

В вашем конкретном случае ключ кортежа должен содержать:

  • Текущий пользователь, потому что вы хотите, чтобы документы были видны только этому пользователю
  • Документ "владелец ", потому что вам нужно отсортировать по этому значению.
  • Документ" когда ", потому что вам нужно отсортировать по этому значению.

Согласно основному правилу, вам нужноодин документ CouchDB, содержащий все это.Ваша текущая схема (текущий пользователь и владелец документа в документе «пользователь», владелец документа и когда в документе «документ») не объединяет необходимые данные, поэтому вам необходимо изменить их.

Мое предложениебудет использовать «общий» документ со следующей структурой:

{ 
   owner : 'id-of-aaron', 
   followers : [ 'id-of-bob', 'id-of-mike', 'id-of-melissa' ],
   docs : {
     'id-of-doc-1' : '2010-09-08',
     'id-of-doc-2' : '2010-09-07',
     'id-of-doc-3' : '2010-11-27'
   }
}

Вам необходимо обновлять эту структуру всякий раз, когда пользователь следует / отменяет подписку на владельца, или владелец добавляет или удаляет документ.Оттуда вы можете просто испустить:

for (var docid in doc.docs) 
  for (var i in doc.followers) {
    emit ([doc.followers[i], doc.owner, doc.docs[docid]], { _id : docid });
  }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...