更具体地说,在 Raven DB 中,我想创建一个带有类似签名的通用方法;
public void Clear<T>() {...
然后让 Raven DB 清除给定类型的所有文档。
我从 Ayende 的其他帖子中了解到类似的问题,您需要一个索引才能批量执行此操作。
我认为这将涉及创建一个映射每种文档类型的索引——这似乎需要做很多工作。
有谁知道一种有效的方法来创建像上面这样直接在数据库中执行 set delete 的方法?
更具体地说,在 Raven DB 中,我想创建一个带有类似签名的通用方法;
public void Clear<T>() {...
然后让 Raven DB 清除给定类型的所有文档。
我从 Ayende 的其他帖子中了解到类似的问题,您需要一个索引才能批量执行此操作。
我认为这将涉及创建一个映射每种文档类型的索引——这似乎需要做很多工作。
有谁知道一种有效的方法来创建像上面这样直接在数据库中执行 set delete 的方法?
我假设您想从 .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/Hilo/", collectionName);
if (hilo != null) {
session.Advanced.DocumentStore.DatabaseCommands.Delete(hilo.Key, hilo.Etag);
}
collectionName
您的收藏的实际名称在哪里。
第一个操作删除项目。第二个删除HiLo 文件。
另请查看官方文档 -如何使用 index 删除或更新文档。
经过大量实验,我发现答案很简单,虽然远非显而易见;
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 可能会使用它,这可能会导致你的查询似乎没有返回你插入的数据:
我也遇到了这个问题,这是对我有用的解决方案。我只在一个测试项目中工作,所以对于更大的数据库来说这可能会很慢,但是 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();
}
}