Pregunta

Digamos que estoy escribiendo una aplicación de análisis de registro. El objeto de dominio principal sería un LogEntry. Adicionalmente. los usuarios de la aplicación definen un LogTopic que describe qué entradas de registro les interesan. A medida que la aplicación recibe entradas de registro, las agrega a couchDB y también las compara con todas las LogTopics en el sistema para ver si coinciden con los criterios del tema . Si es así, el sistema debería registrar que la entrada coincide con el tema. Por lo tanto, existe una relación de muchos a muchos entre LogEntries y LogTopics.

Si estuviera almacenando esto en un RDBMS, haría algo como:

CREATE TABLE Entry (
 id int,
 ...
)

CREATE TABLE Topic (
 id int,
 ...
)

CREATE TABLE TopicEntryMap (
 entry_id int,
 topic_id int
)

Usando CouchDB Primero intenté tener solo dos tipos de documentos. Tendría un tipo LogEntry, parecido a esto:

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

y tendría un tipo LogTopic, similar a este:

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

Puede ver que represento la relación utilizando un campo matching_entries en cada documento de LogTopic para almacenar una lista de identificadores de documentos de LogEntry. Esto funciona bien hasta cierto punto, pero tengo problemas cuando varios clientes intentan agregar una entrada coincidente a un tema. Ambos intentan actualizaciones optimistas, y uno falla. La solución que estoy usando ahora es esencialmente reproducir el enfoque RDBMS y agregar un tercer tipo de documento, algo así como:

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

Esto funciona y supera los problemas de actualización simultánea, pero tengo dos reservas:

  1. Me preocupa que solo esté usando esto enfoque porque es lo que haría en una base de datos relacional. Me pregunto si hay un sofá más parecido a DB (¿relajante?) solución.
  2. Mis vistas ya no pueden recuperar todas las entradas para un tema específico en una llamada. Mi la solución anterior permitía eso (si yo usó el parámetro include_docs).

¿Alguien tiene una mejor solución para mí? ¿Me ayudaría si también publicara las vistas que estoy usando?

¿Fue útil?

Solución

Tu enfoque está bien. Usar CouchDB no significa que abandonarás el modelado relacional. Necesitará ejecutar dos consultas, pero eso se debe a que es & Quot; join & Quot ;. Las consultas SQL con combinaciones también son lentas, pero la sintaxis SQL le permite expresar la consulta en una sola declaración.

En mis pocos meses de experiencia con CouchDB, esto es lo que descubrí:

  1. Sin esquema, por lo que diseñar los modelos de aplicación es rápido y flexible
  2. CRUD está ahí, por lo que desarrollar su aplicación es rápido y flexible
  3. Adiós inyección SQL
  4. Lo que sería una unión SQL requiere un poco más de trabajo en CouchDB

Dependiendo de sus necesidades, descubrí que couchdb-lucene también es útil para crear consultas más complejas.

Otros consejos

Publiqué esta pregunta en la lista de correo de usuarios de couchdb y Nathan Stott < a href = "http://markmail.org/message/vsvwyz4rccc33jox" rel = "noreferrer"> me señaló a publicación de blog muy útil de Christopher Lenz

Intentaría configurar la relación para que LogEntrys sepa a qué LogTopics pertenecen. De esa manera, insertar un LogEntry no producirá conflictos ya que LogTopics no necesitará ser cambiado.

Entonces, una función de mapa simple emitiría LogEntry una vez por cada LogTopic al que pertenece, esencialmente construyendo su TopicEntryMap sobre la marcha:

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

De esta forma, al consultar la vista con un argumento ?key=<topic> obtendrá todas las entradas que pertenecen a un tema.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top