Pergunta

Vamos dizer que eu estou escrevendo um aplicativo de análise de log. O principal objeto de domínio seria um LogEntry. Além do que, além do mais. os usuários do aplicativo definir uma LogTopic que descreve o que as entradas estão interessados ??em iniciar sessão. Como o aplicativo recebe entradas de log Acrescenta-los para CouchDB, e também verifica-las contra todas as LogTopics no sistema para ver se eles correspondem aos critérios no tópico . Se isso acontecer, então o sistema deve gravar que a entrada corresponda ao tópico. Assim, há uma relação de n para n entre LogEntries e LogTopics.

Se eu estivesse armazenando isso em um RDBMS eu faria algo como:

CREATE TABLE Entry (
 id int,
 ...
)

CREATE TABLE Topic (
 id int,
 ...
)

CREATE TABLE TopicEntryMap (
 entry_id int,
 topic_id int
)

Usando CouchDB I primeiro tentou ter apenas dois tipos de documentos. Eu tenho um tipo LogEntry, procurando algo como isto:

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

e eu teria um tipo LogTopic, procurando algo como isto:

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

Você pode ver que eu represento o relacionamento usando um campo matching_entries em cada documentos LogTopic para armazenar uma lista de IDs de documentos LogEntry. Isso funciona bem até um certo ponto, mas eu tenho problemas quando vários clientes estão ambas tentando adicionar uma entrada correspondente a um tópico. Ambos tentam atualizações otimistas, e uma falha. A solução que eu estou usando agora é essencialmente reproduzir a abordagem RDBMS, e adicionar um terceiro tipo de documento, algo como:

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

Isso funciona, e consegue passar os problemas de atualização simultâneas, mas eu tenho duas reservas:

  1. Preocupa-me que eu estou apenas usando este aproximar porque é o que eu faria em um banco de dados relacional. Gostaria de saber se há um mais CouchDB-like (relaxful?) solução.
  2. Minhas opiniões não podem mais recuperar todas as entradas para a tópico específico em uma chamada. Minhas soluo anterior permitia que (se eu usado o parâmetro include_docs).

Alguém tem uma solução melhor para mim? Ajudaria se eu também postou os pontos de vista que estou usando?

Foi útil?

Solução

A sua abordagem é muito bem. Usando CouchDB não significa que você só vai abandonar a modelagem relacional. Você terá necessidade de executar duas consultas, mas isso é porque esta é uma "join". consultas SQL com junções também são lentos, mas a sintaxe SQL permite expressar a consulta em um comunicado.

Em meus poucos meses de experiência com CouchDB este é o que eu descobri:

  1. No esquema, para desenvolver os modelos de aplicação é rápido e flexível
  2. CRUD está lá, então desenvolver sua aplicação é rápida e flexível
  3. injeção Adeus SQL
  4. O que seria uma junção SQL leva um pouco mais de trabalho no CouchDB

Dependendo de suas necessidades Descobri que couchdb-Lucene também é útil para a construção de consultas mais complexas.

Outras dicas

Cruzei-postei esta pergunta aos couchdb usuários Mailing List e Nathan Stott < a href = "http://markmail.org/message/vsvwyz4rccc33jox" rel = "noreferrer"> apontou-me a um muito útil post por Christopher Lenz

Eu ia tentar configurar a relação de modo que LogEntrys saber para que LogTopics pertencem. Dessa forma, a inserção de um LogEntry não produzirá conflitos como os LogTopics não precisará ser alterado.

Em seguida, uma função simples mapa emitiria o LogEntry uma vez para cada LogTopic a que pertence, essencialmente, construir o seu TopicEntryMap na mosca:

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

Desta forma, consultando a visão com um argumento ?key=<topic> vai lhe dar todas as entradas que pertencem a um tópico.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top