2012-04-13 14 views
17

Più specificamente in Raven DB, voglio creare un metodo generico con una firma simile;Raven DB: Come posso cancellare tutti i documenti di un determinato tipo

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

Poi hanno Raven DB cancellare tutti i documenti di un dato tipo.

Ho capito da altri post di Ayende a domande simili che avresti bisogno di un indice in atto per farlo in gruppo.

Penso che ciò implicherebbe la creazione di un indice che mappa ogni tipo di documento: questo sembra molto lavoro.

Qualcuno sa un modo efficiente di creare un metodo come quello sopra che farà un set di eliminazione direttamente nel database?

risposta

9

Dopo molti esperimenti ho trovato la risposta ad essere abbastanza semplice, anche se tutt'altro che scontato;

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()); 
} 

Certo che quasi certamente non definiresti il ​​tuo indice e fare la vostra eliminazione in un colpo solo, ho messo questo come un metodo unico per brevità.

La mia implementazione definisce gli indici all'avvio dell'applicazione come raccomandato dalla documentazione.

Se si desidera utilizzare questo approccio per indicizzare effettivamente una proprietà di T, sarà necessario vincolare T. Ad esempio se si dispone di un IEntity ereditato da tutte le classi di documenti e questa classe specifica un ID di proprietà. Quindi un 'dove T: IEntity' ti consentirebbe di usare quella proprietà nell'indice.

E 'stato detto in altri luoghi, ma è anche la pena notare che una volta che si definisce un indice statico Raven probabilmente usarlo, questo può causare le vostre domande a apparentemente non restituiscono i dati che hai inserito:

RavenDB Saving to disk query

+1

Come contributore RavenDB, non è consigliabile in questo modo, poiché si sta creando un indice inutilmente. Invece, raccomando la risposta di @ alexn: http://stackoverflow.com/a/13049179/536 –

4

È possibile farlo usando: http://blog.orangelightning.co.uk/?p=105

+0

Ciao Ayende, la tua risposta è stata davvero utile, ma non proprio quello che stavo cercando. Dopo molte sperimentazioni e informazioni su Raven ho trovato la soluzione che stavo cercando. Pubblicherò la risposta qui a breve per gli altri. –

+0

Ho trovato che questa è la soluzione non programmatica più semplice. – Keith

+0

Non ho mai trovato il comando Reset menzionato in quel blog. Finito con un indice simile a quello di Ryan. –

22

Presumo che si desideri eseguire questa operazione dal client .NET. In tal caso, usare lo standard DocumentsByEntityName index:

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); 
} 

Dove collectionName è il nome effettivo della vostra collezione.

La prima operazione elimina gli elementi. Il secondo elimina lo HiLo file.

Consultare anche la documentazione ufficiale - How to delete or update documents using index.

+1

questo è imho un modo migliore rispetto alla risposta accettata in quanto non richiede la creazione di un indice e cancella tutti i documenti che potrebbero non essere incluso se stavi cancellando usando un indice esistente. – wal

+0

Mi piace anche cancellare il relativo documento HiLo per reimpostare gli ID. @alexn posso modificare il tuo codice per aggiungerlo? 'var hilo = session.Advanced.DocumentStore.DatabaseCommands.Get (" Raven/Hilo/themes "); session.Advanced.DocumentStore.DatabaseCommands.Delete (hilo.Key, hilo.Etag); ' – SandRock

+0

@SandRock assolutamente :) – alexn

6

Ho avuto anche questo problema e questa è la soluzione che ha funzionato per me. Sto solo lavorando in un progetto di test, quindi questo potrebbe essere lento per un db più grande, ma la risposta di Ryan non ha funzionato per me.

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

Sono in esecuzione anche test su un negozio Embedded e solo la soluzione ha funzionato per me. Un post pubblicato su Google Gruppi (https://groups.google.com/forum/#!topic/ravendb/QqZPrRUwEkE) suggerisce che è necessario prima creare l'indice DocumentsByEntityName in questo scenario: "new RavenDocumentsByEntityName(). Execute (store) ;" Fatto ciò ho ancora trovato che i documenti che avrebbero dovuto essere eliminati erano ancora presenti (ho anche impedito che venissero restituite query non aggiornate, quindi anche questa non era la risposta). – rogersillito

Problemi correlati