2012-04-13 13 views
17

Más específicamente en Raven DB, quiero crear un método genérico con una firma como;Raven DB: ¿Cómo puedo eliminar todos los documentos de un tipo determinado

public void Clear<T>() {... 

Haga que Raven DB borre todos los documentos del tipo dado.

Entiendo de otras publicaciones de Ayende a preguntas similares que necesitaría un índice para hacer esto como un lote.

Creo que esto implicaría crear un índice que mapee cada tipo de documento, esto parece mucho trabajo.

¿Alguien sabe una forma eficiente de crear un método como el anterior que hará un conjunto de eliminar directamente en la base de datos?

Respuesta

9

Después de mucha experimentación he encontrado la respuesta a ser bastante simple, aunque lejos de ser evidente;

public void Clear<T>() 
{ 
    session.Advanced.DocumentStore.DatabaseCommands.PutIndex(indexName, new IndexDefinitionBuilder<T> 
    { 
     Map = documents => documents.Select(entity => new {}) 
    }); 

    session.Advanced.DatabaseCommands.DeleteByIndex(indexName, new IndexQuery()); 
} 

Por supuesto, es casi seguro que no se definirían su índice y hacer su eliminación en una sola vez, he puesto esto como un método único en aras de la brevedad.

Mi propia implementación define los índices en el inicio de la aplicación como lo recomienda la documentación.

Si desea utilizar este enfoque para realmente indexar una propiedad de T, deberá restringir T. Por ejemplo, si tengo un IEntity del que todas mis clases de documento heredan y esta clase especifica un Id de propiedad. Entonces, 'donde T: IEntity' le permitiría usar esa propiedad en el índice.

Se ha dicho en otros lugares, pero es también digno de mención que una vez que se define un índice estático Cuervo probablemente usarlo, esto puede causar que sus consultas al parecer no devuelven datos que ha insertado:

RavenDB Saving to disk query

+1

Como colaborador de RavenDB, no lo recomiendo de esta manera, ya que está creando un índice innecesariamente. En su lugar, recomiendo la respuesta de @ alexn: http://stackoverflow.com/a/13049179/536 –

4

se puede hacer eso usando: http://blog.orangelightning.co.uk/?p=105

+0

Hola Ayende, tu respuesta fue realmente útil, pero no exactamente lo que estaba buscando. Después de mucha experimentación y aprendizaje sobre Raven, encontré la solución que estaba buscando. Voy a publicar la respuesta aquí en breve para otros. –

+0

Encontré que esta es la solución no programática más fácil. – Keith

+0

Nunca encontré el comando Restablecer mencionado en ese blog. Terminó con un índice similar al de Ryan. –

22

Supongo que desea hacer esto desde el cliente .NET. Si es así, utilice el estándar DocumentsByEntityName índice:

var indexQuery = new IndexQuery { Query = "Tag:" + collectionName }; 
session.Advanced.DocumentStore.DatabaseCommands.DeleteByIndex(
    "Raven/DocumentsByEntityName", 
    indexQuery, 
    new BulkOperationOptions { AllowStale = true }); 

var hilo = session.Advanced.DocumentStore.DatabaseCommands.Get("Raven/H‌​ilo/", collectionName); 
if (hilo != null) { 
    session.Advanced.DocumentStore.DatabaseCommands.Delete(hilo.‌​Key, hilo.Etag); 
} 

Dónde collectionName es el nombre real de su colección.

La primera operación elimina los elementos. El segundo borra el HiLo file.

Consulte también la documentación oficial - How to delete or update documents using index.

+1

, esta es una forma mejor que la aceptada, ya que no requiere la creación de un índice y borra cualquier documento que pueda no serlo. se incluirá si está eliminando usando un índice existente. – wal

+0

También me gusta eliminar el documento HiLo relacionado para restablecer los ID. @alexn ¿puedo editar tu código para agregar esto? 'var hilo = session.Advanced.DocumentStore.DatabaseCommands.Get (" Raven/Hilo/themes "); session.Advanced.DocumentStore.DatabaseCommands.Delete (hilo.Key, hilo.Etag); ' – SandRock

+0

@SandRock absolutamente :) – alexn

6

Tuve este problema también y esta es la solución que funcionó para mí. Solo estoy trabajando en un proyecto de prueba, así que esto podría ser lento para un DB más grande, pero la respuesta de Ryan no funcionó para mí.

public static void ClearDocuments<T>(this IDocumentSession session) 
    { 
     var objects = session.Query<T>().ToList(); 
     while (objects.Any()) 
     { 
      foreach (var obj in objects) 
      { 
       session.Delete(obj); 
      } 

      session.SaveChanges(); 
      objects = session.Query<T>().ToList(); 
     } 
    } 
+0

También estoy ejecutando pruebas en una tienda Embedded y solo tu solución funcionó para mí. Una publicación de Google Groups (https://groups.google.com/forum/#!topic/ravendb/QqZPrRUwEkE) sugiere que primero debe crear el índice DocumentsByEntityName en este escenario: "new RavenDocumentsByEntityName(). Execute (store) ; " Al haber hecho esto, todavía encontré que los documentos que deberían haberse eliminado todavía estaban presentes (también evito que se devuelvan consultas obsoletas, por lo que esta tampoco fue la respuesta). – rogersillito

Cuestiones relacionadas