更具体地说,在Raven DB中,我想创建一个带有签名的通用方法,如;
public void Clear<T>() {...
然后让Raven DB清除给定类型的所有文档。
我从Ayende的其他帖子中了解到类似的问题,您需要有一个索引来批量执行此操作。
我认为这将涉及创建一个映射每种文档类型的索引 - 这似乎很多工作。
有没有人知道一种创建上述方法的有效方法,可以直接在数据库中进行集删除?
答案 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/Hilo/", 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可能会使用它,这可能会导致你的查询看起来没有返回你插入的数据:
答案 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)