Raven DB: как я могу удалить все документы определенного типа?

17

В частности, в Raven DB я хочу создать общий метод с такой сигнатурой, как:

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

Затем Raven DB очистит все документы данного типа.

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

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

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

    
задан Ryan Worsley 13.04.2012 в 20:07
источник

4 ответа

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 Сохранение запроса на диск

    
ответ дан Ryan Worsley 19.04.2012 в 08:30
источник
  • Как вкладчик RavenDB, я не рекомендую этот способ, поскольку вы создаете индекс без необходимости. Вместо этого я рекомендую ответить @ alexn: stackoverflow.com/a/13049179/536 –  Judah Himango 03.05.2016 в 16:04
23

Предполагаю, что вы хотите сделать это от клиента .NET. Если это так, используйте стандартный 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);
}

Где collectionName - это фактическое имя вашей коллекции.

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

Также ознакомьтесь с официальной документацией - Как удалить или обновить документы с помощью индекса .

    
ответ дан alexn 24.10.2012 в 14:25
источник
  • это imho лучший путь, чем принятый ответ, поскольку он не требует создания индекса, и он удаляет любые документы, которые не могут быть включены, если вы удаляете использование существующего индекса. –  wal 11.11.2014 в 01:22
  • Я также хотел бы удалить связанный документ HiLo для сброса идентификаторов. @alexn могу ли я изменить свой код, чтобы добавить это? var hilo = session.Advanced.DocumentStore.DatabaseCommands.Get ("Raven / Hilo / themes"); session.Advanced.DocumentStore.DatabaseCommands.Delete (hilo.Key, hilo.Etag); –  SandRock 28.10.2015 в 11:16
  • @SandRock абсолютно :) –  alexn 28.10.2015 в 14:21
  • Выше кода имеет некоторые синтаксические ошибки. Здесь бесплатный код ошибки 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); } –  Sajid Ali 03.10.2017 в 13:53
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();
        }
    }
    
ответ дан peinearydevelopment 09.01.2014 в 18:59
источник
  • Я также запускаю тесты против магазина Embedded, и только мое решение работало для меня. Сообщение в группах Google (groups.google.com/forum/#!topic/ravendb/QqZPrRUwEkE) предлагает вам сначала создать индекс DocumentByEntityName в этом сценарии: «new RavenDocumentsByEntityName (). Выполнить (сохранить); Сделав это, я все еще обнаружил, что документы, которые должны были быть удалены, все еще присутствуют (я также предотвращаю возврат старых запросов, так что это тоже не ответ). –  rogersillito 25.02.2015 в 19:26
4

Вы можете сделать это, используя: Ссылка

    
ответ дан Ayende Rahien 14.04.2012 в 17:00
источник
  • Привет Айенде, ваш ответ был действительно полезен, но не совсем то, что я искал. После долгих экспериментов и изучения Raven я нашел решение, которое я искал. Я отправлю ответ здесь для других. –  Ryan Worsley 19.04.2012 в 08:12
  • Я нашел это самым легким непрограммным решением. –  Keith 17.05.2013 в 19:44
  • Я никогда не встречал команду Reset, упомянутую в этом блоге. Закончился индекс, похожий на Райана. –  Nils Magne Lunde 23.12.2013 в 12:34