2012-04-13 16 views
17

Dokładniej w Raven DB, chcę utworzyć ogólną metodę z podpisem podobnym;Raven DB: Jak mogę usunąć wszystkie dokumenty danego typu?

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

Następnie Raven DB wyczyść wszystkie dokumenty danego typu.

Rozumiem z innych postów Ayende na podobne pytania, które wymagają indeksu w miejscu, aby zrobić to jako partia.

Myślę, że wymagałoby to stworzenia indeksu mapującego każdy typ dokumentu - wydaje się, że to dużo pracy.

Czy ktoś zna skuteczny sposób tworzenia metody podobnej do powyższej, która spowoduje usunięcie zestawu bezpośrednio w bazie danych?

Odpowiedz

9

Po wielu eksperymentach znalazłem odpowiedź jest dość prosta, choć dalekie od oczywistości;

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

Oczywiście, że prawie na pewno nie byłoby zdefiniować indeks i zrobić swoją kasowania za jednym razem, mam umieścić to jako pojedyncza metoda zwięzłości.

Moje własne wdrożenie definiuje indeksy uruchamiania aplikacji zgodnie z zaleceniami w dokumentacji.

Jeśli chcesz użyć tego podejścia do faktycznego indeksowania właściwości T, musisz ograniczyć T. Na przykład, jeśli posiadam IEntity, że wszystkie moje klasy dokumentów dziedziczą, a ta klasa określa identyfikator właściwości. Następnie "where T: IEntity" pozwoli ci użyć tej właściwości w indeksie.

Mówi się w innych miejscach, ale warto też zauważyć, że po zdefiniowaniu indeksu statyczne Raven prawdopodobnie będzie go używać, może to spowodować zapytania nie do pozornie zwrócić dane, które zostały wstawione:

RavenDB Saving to disk query

+1

Jako użytkownik RavenDB, nie polecam w ten sposób, ponieważ niepotrzebnie tworzysz indeks. Zamiast tego polecam odpowiedź @ alexn: http://stackoverflow.com/a/13049179/536 –

4

Można to zrobić przy użyciu: http://blog.orangelightning.co.uk/?p=105

+0

Cześć Ayende, odpowiedź była bardzo przydatna, ale nie do końca tego, czego szukałem. Po wielu eksperymentach i poznaniu Ravena znalazłem rozwiązanie, którego szukałem. Wkrótce opublikuję odpowiedź dla innych. –

+0

Stwierdziłem, że jest to najprostsze rozwiązanie nieautomatyczne. – Keith

+0

Nigdy nie znalazłem polecenia Reset wymienionego na tym blogu. Skończyło się na indeksie podobnym do indeksu Ryana. –

22

Zakładam, że chcesz to zrobić z klienta .NET. Jeśli tak, należy użyć standardowego 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); 
} 

Gdzie collectionName jest rzeczywista nazwa kolekcji.

Pierwsza operacja usuwa elementy. Drugi usuwa HiLo file.

Zobacz również oficjalną dokumentację - How to delete or update documents using index.

+1

jest to imho lepszy sposób niż zaakceptowana odpowiedź, ponieważ nie wymaga ona utworzenia indeksu i usuwa wszelkie dokumenty, które mogą nie być być uwzględnione, jeśli usuwałeś przy użyciu istniejącego indeksu. – wal

+0

Chcę również usunąć powiązany dokument HiLo, aby zresetować identyfikatory. @alexn mogę edytować twój kod, aby to dodać? 'var hilo = session.Advanced.DocumentStore.DatabaseCommands.Get (" Raven/Hilo/themes "); session.Advanced.DocumentStore.DatabaseCommands.Delete (hilo.Key, hilo.Etag); ' – SandRock

+0

@SandRock absolutnie :) – alexn

6

Miałem również ten problem i to rozwiązanie sprawdziło się u mnie. Pracuję tylko w projekcie testowym, więc może to być powolne dla większego db, ale odpowiedź Ryana nie działa dla mnie.

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

Przeprowadzam również testy w sklepie Embedded i działa tylko dla mnie. W poście w Grupach dyskusyjnych Google (https://groups.google.com/forum/#!topic/ravendb/QqZPrRUwEkE) sugeruje się, aby najpierw utworzyć indeks DocumentsByEntityName w tym scenariuszu: "new RavenDocumentsByEntityName(). Execute (sklep) ; " Po zrobieniu tego nadal stwierdziłem, że dokumenty, które powinny zostać usunięte, nadal były obecne (zapobiegam również zwracaniu starych zapytań, więc nie było to również odpowiedzią). – rogersillito

Powiązane problemy