Raven DB:如何删除给定类型的所有文档

时间:2012-04-13 18:07:36

标签: ravendb

更具体地说,在Raven DB中,我想创建一个带有签名的通用方法,如;

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

然后让Raven DB清除给定类型的所有文档。

我从Ayende的其他帖子中了解到类似的问题,您需要有一个索引来批量执行此操作。

我认为这将涉及创建一个映射每种文档类型的索引 - 这似乎很多工作。

有没有人知道一种创建上述方法的有效方法,可以直接在数据库中进行集删除?

4 个答案:

答案 0 :(得分:23)

我假设您要从.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 :(得分: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,我的所有文档类都继承,并且这个类指定了属性Id。然后'where T:IEntity'将允许您在索引中使用该属性。

在其他地方已经说过了,但是值得注意的是,一旦你定义了一个静态索引,Raven可能会使用它,这可能会导致你的查询看起来没有返回你插入的数据:

RavenDB Saving to disk query

答案 2 :(得分:7)

我也有这个问题,这是对我有用的解决方案。我只是在测试项目中工作,所以对于更大的数据库来说这可能会很慢,但Ryan的答案对我来说并不适用。

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

答案 3 :(得分:4)