2012-04-13 3 views
17

Более конкретно, в Raven DB я хочу создать общий метод с подобной сигнатурой;Raven DB: Как я могу удалить все документы определенного типа

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

Тогда Raven DB удалить все документы данного типа.

Насколько я понимаю из других сообщений Айенде, вам нужен указатель, чтобы сделать это как пакет.

Я думаю, что это связано с созданием индекса, который отображает каждый тип документа - это похоже на большую работу.

Кто-нибудь знает эффективный способ создания метода, подобного описанному выше, который будет выполнять набор delete непосредственно в базе данных?

ответ

9

После долгих экспериментов я нашел ответ довольно прост, хотя далеко не очевидно;

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

Конечно, вы почти наверняка не будет определять ваш индекс и делать удаление за один раз, я положил это как единственный метод для краткости.

Моя собственная реализация определяет индексы при запуске приложения, как рекомендовано в документации.

Если вы хотите использовать этот подход для фактического индексирования свойства T, вам нужно будет ограничить T. Например, если у меня есть IEntity, что все мои классы документов наследуются, а этот класс указывает идентификатор свойства. Тогда «где T: IEntity» позволит вам использовать это свойство в индексе.

Это было сказано в других местах, но это также стоит отметить, что, как только вы определить статический индекс Raven будет, вероятно, использовать его, это может привести к вашим запросам, казалось бы, не возвращать данные, которые вы вставили:

RavenDB Saving to disk query

+1

Как вкладчик RavenDB, я не рекомендую этот способ, так как вы создаете индекс без необходимости. Вместо этого я рекомендую ответить @ alexn: http://stackoverflow.com/a/13049179/536 –

4

Вы можете сделать это с помощью: http://blog.orangelightning.co.uk/?p=105

+0

Привет Айенде, ваш ответ был действительно полезен, но не совсем то, что я искал. После долгих экспериментов и изучения Raven я нашел решение, которое я искал. Я отправлю ответ здесь для других. –

+0

Я нашел это самым легким непрограммным решением. – Keith

+0

Я никогда не встречал команду Reset, упомянутую в этом блоге. Закончился индекс, похожий на Райана. –

22

Предполагаю, что вы хотите сделать это от клиента .NET. Если да, то используйте стандартный DocumentsByEntityName индекс:

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

Где collectionName фактическое название вашей коллекции.

Первая операция удаляет элементы. Второй удаляет HiLo file.

Также ознакомьтесь с официальной документацией - How to delete or update documents using index.

+1

это imho лучший путь, чем принятый ответ, поскольку он не требует создания индекса, и он удаляет любые документы, которые могут не быть быть включенным, если вы удаляете использование существующего индекса. – wal

+0

Я также хотел бы удалить связанный документ HiLo для сброса идентификаторов. @alexn могу ли я изменить свой код, чтобы добавить это? 'var hilo = session.Advanced.DocumentStore.DatabaseCommands.Get (" Raven/Hilo/themes "); session.Advanced.DocumentStore.DatabaseCommands.Delete (hilo.Key, hilo.Etag); ' – SandRock

+0

@SandRock абсолютно :) – alexn

6

У меня была эта проблема, и это решение, которое сработало для меня. Я работаю только в тестовом проекте, так что это может быть медленным для большего db, но ответ Райана не работает для меня.

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

Я также выполняю тесты против встроенного магазина, и только мое решение сработало для меня. Сообщение в группах Google (https://groups.google.com/forum/#!topic/ravendb/QqZPrRUwEkE) предлагает вам сначала создать индекс DocumentByEntityName в этом сценарии: «new RavenDocumentsByEntityName(). Выполнить (сохранить) ;» Сделав это, я все еще обнаружил, что документы, которые должны были быть удалены, все еще присутствуют (я также препятствую возврату старых запросов, так что это тоже не ответ). – rogersillito

Смежные вопросы