представляя отношения многие ко многим в couchDB
-
10-07-2019 - |
Вопрос
Допустим, я пишу приложение для анализа журналов. Основным объектом домена будет LogEntry. К тому же. пользователи приложения определяют LogTopic, который описывает, какие записи журнала им интересны. Когда приложение получает записи журнала, оно добавляет их в couchDB, а также проверяет их по всем LogTopics в системе, чтобы увидеть, соответствуют ли они критериям в теме , Если это так, то система должна записать, что запись соответствует теме. Таким образом, между LogEntries и LogTopics существует отношение «многие ко многим». Р>
Если бы я хранил это в РСУБД, я бы сделал что-то вроде:
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'
}
Это работает и устраняет проблемы одновременного обновления, но у меня есть две оговорки:
<Ол>У кого-нибудь есть лучшее решение для меня? Поможет ли мне опубликовать просмотры, которые я использую?
Решение
Ваш подход в порядке. Использование CouchDB не означает, что вы просто откажетесь от реляционного моделирования. Вам нужно будет выполнить два запроса, но это потому, что это & Quot; join & Quot ;. Запросы SQL с объединениями также являются медленными, но синтаксис SQL позволяет выразить запрос в одном выражении.
За несколько месяцев работы с CouchDB я обнаружил следующее:
<Ол>В зависимости от ваших потребностей я обнаружил, что couchdb-lucene также полезен для создания более сложных запросов.
Другие советы
Я добавил этот вопрос в список рассылки пользователей couchdb и Натана Стотта <<> a href = "http://markmail.org/message/vsvwyz4rccc33jox" rel = "noreferrer"> указал мне на a очень полезное сообщение в блоге Кристофера Ленца
Я бы попытался установить отношение так, чтобы LogEntrys знал, к каким LogTopics они принадлежат. Таким образом, вставка LogEntry не вызовет конфликтов, так как LogTopics не нужно будет менять.
Затем простая функция карты будет генерировать LogEntry один раз для каждой LogTopic, к которой она принадлежит, по сути, создавая ваш TopicEntryMap на лету:
"map": function (doc) {
doc.topics.map(function (topic) {
emit(topic, doc);
});
}
Таким образом, запрос представления с аргументом ?key=<topic>
даст вам все записи, относящиеся к теме.