17

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

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

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

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

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

有谁知道一种有效的方法来创建像上面这样直接在数据库中执行 set delete 的方法?

4

4 回答 4

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 文件

另请查看官方文档 -如何使用 index 删除或更新文档

于 2012-10-24T12:25:17.237 回答
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,我的所有文档类都从该 IEntity 继承,并且该类指定了一个属性 Id。然后一个 'where T : IEntity' 将允许您在索引中使用该属性。

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

RavenDB 保存到磁盘查询

于 2012-04-19T06:30:00.843 回答
8

我也遇到了这个问题,这是对我有用的解决方案。我只在一个测试项目中工作,所以对于更大的数据库来说这可能会很慢,但是 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();
        }
    }
于 2014-01-09T17:59:15.313 回答
4

你可以这样做: http ://blog.orangelightning.co.uk/?p=105

于 2012-04-14T15:00:18.987 回答