2009-11-30 2 views
3

Предположим, что я пишу приложение анализа журнала. Основным объектом домена будет LogEntry. К тому же. пользователи приложения определяют LogTopic, который описывает, какие записи журнала они интересуют. Поскольку приложение получает записи журнала, оно добавляет их в couchDB, а также проверяет их на всех LogTopics в системе, чтобы узнать, соответствуют ли они критериям в теме , Если это произойдет, система должна записать, что запись соответствует теме. Таким образом, между LogEntries и LogTopics существует взаимосвязь «многие-ко-многим»., представляющий отношение «многие ко многим» в couchDB

Если бы я хранить это в РСУБД я бы сделать что-то вроде:

CREATE TABLE Entry (
id int, 
... 
) 

CREATE TABLE Topic (
id int, 
... 
) 

CREATE TABLE TopicEntryMap (
entry_id int, 
topic_id int 
) 

Использование CouchDB я первый попытался имея только два типа документа. Я бы тип LogEntry, смотря что-то вроде этого:

{ 
    'type': 'LogEntry', 
    'severity': 'DEBUG', 
    ... 
} 

и я бы тип LogTopic, смотря что-то вроде этого:

{ 
    'type': 'LogTopic', 
    'matching_entries': ['log_entry_1','log_entry_12','log_entry_34',....], 
    ... 
} 

Вы можете видеть, что я представляю отношения по используя поле matching_entries в каждом документе LogTopic для хранения списка идентификаторов документа LogEntry. Это работает до некоторой степени, но у меня возникают проблемы, когда несколько клиентов пытаются добавить соответствующую тему в тему. Обе попытки оптимистичные обновления, и один не удается. Решение я использую в настоящее время является, по существу, воспроизводит RDBMS подход, и добавить третий тип документа, что-то вроде:

{ 
    'type':'LogTopicToLogEntryMap', 
    'topic_id':'topic_12', 
    'entry_id':'entry_15' 
} 

Это работает, и получает мимо одновременно с обновлением вопросов, но у меня есть две оговорки:

  1. Я беспокоюсь, что я просто использую этот подход , потому что это то, что я сделал бы в реляционной БД. Интересно, есть ли больше couchDB-like (relaxable?) решение.
  2. Мое мнение больше не может получить все записи для определенной темы за один звонок. Мое предыдущее решение разрешило, что (если I использовал параметр include_docs).

У кого-нибудь есть лучшее решение для меня? Помогло бы мне, если бы я также разместил мнения, которые я использую?

ответ

4

Ваш подход прекрасен. Использование CouchDB не означает, что вы просто откажетесь от реляционного моделирования. Вам понадобится выполнить два запроса, но это потому, что это «соединение». SQL-запросы с объединениями также медленны, но синтаксис SQL позволяет вам выражать запрос в одном выражении.

В моих несколько месяцев опыта работы с CouchDB это то, что я обнаружил:

  1. Нет схемы, поэтому разработка модели приложения быстро и гибко
  2. CRUD есть, поэтому развивается ваше приложение быстрый и гибкий
  3. Прощайте SQL инъекции
  4. что бы SQL присоединиться занимает немного больше работы в CouchDB

В зависимости от ваших потребностей я обнаружил, что couchdb-lucene также полезен для построения более сложных запросов.

11

Я перекрестно-отправил этот вопрос на couchdb users mailing list и Натан Стотт pointed me tovery helpful blog post Кристофером Ленца

+0

+1 Наконец, у меня был этот вопрос с тех пор, как я узнал о couchdb и mongodb. Я знал, что у кого-то есть ответ. – Xeoncross

+0

Это очень хороший блогпост, но речь идет о взаимоотношениях один-ко-многим (blogpost - комментарий). Любые примеры того, как обращаться со многими из многих? – GijsjanB

0

Я хотел бы попробовать настройки отношения так, чтобы LogEntrys знать, к которому они принадлежат LogTopics. Таким образом, вставка LogEntry не приведет к конфликтам, так как LogTopics не нужно будет изменять.

Тогда простая функция карта будет испускать LogEntry один раз для каждого LogTopic он принадлежит, по существу, строить свой TopicEntryMap на лету:

"map": function (doc) { 
    doc.topics.map(function (topic) { 
     emit(topic, doc); 
    }); 
} 

Таким образом, запрашивая мнение с ?key=<topic> аргументом даст вы все записи, относящиеся к теме.

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

  • Нет связанных вопросов^_^