从RavenDB检索整个数据集合
我需要从RavenDB获取整个数据收集从RavenDB检索整个数据集合,ravendb,Ravendb,我需要从RavenDB获取整个数据收集用户,并将检索到的结果集与另一组数据进行比较。在这个特定的收藏中有近4000条记录 由于Raven在默认情况下是安全的,因此每次会话的请求数超过或返回最多128条记录时,我都会收到一个异常 我不想将属性Session.Advanced.MaxNumberOfRequestsPerSession设置为更高的值 我应该使用什么查询来获取所有记录的计数?处理这种情况的理想方法是什么?您使用分页,一次读取1024项 int start = 0; while(true
用户
,并将检索到的结果集与另一组数据进行比较。在这个特定的收藏中有近4000条记录
由于Raven在默认情况下是安全的,因此每次会话的请求数超过或返回最多128条记录时,我都会收到一个异常
我不想将属性Session.Advanced.MaxNumberOfRequestsPerSession
设置为更高的值
我应该使用什么查询来获取所有记录的计数?处理这种情况的理想方法是什么?您使用分页,一次读取1024项
int start = 0;
while(true)
{
var current = session.Query<User>().Take(1024).Skip(start).ToList();
if(current.Count == 0)
break;
start+= current.Count;
allUsers.AddRange(current);
}
int start=0;
while(true)
{
var current=session.Query().Take(1024).Skip(start).ToList();
如果(current.Count==0)
打破
开始+=当前的计数;
allUsers.AddRange(当前);
}
在Ayende答案的基础上,这里有一个完整的方法,它确实克服了每个会话30个查询的问题,并且确实返回了所提供类的所有文档:
public static List<T> getAll<T>(DocumentStore docDB) {
return getAllFrom(0, new List<T>(), docDB);
}
public static List<T> getAllFrom<T>(int startFrom, List<T> list, DocumentStore docDB ) {
var allUsers = list;
using (var session = docDB.OpenSession())
{
int queryCount = 0;
int start = startFrom;
while (true)
{
var current = session.Query<T>().Take(1024).Skip(start).ToList();
queryCount += 1;
if (current.Count == 0)
break;
start += current.Count;
allUsers.AddRange(current);
if (queryCount >= 30)
{
return getAllFrom(start, allUsers, docDB);
}
}
}
return allUsers;
}
公共静态列表getAll(DocumentStore docDB){
返回getAllFrom(0,new List(),docDB);
}
公共静态列表getAllFrom(int startFrom、列表列表、DocumentStore docDB){
var allUsers=列表;
使用(var session=docDB.OpenSession())
{
int queryCount=0;
int start=startFrom;
while(true)
{
var current=session.Query().Take(1024).Skip(start).ToList();
查询计数+=1;
如果(current.Count==0)
打破
开始+=当前的计数;
allUsers.AddRange(当前);
如果(查询计数>=30)
{
返回getAllFrom(start、allUsers、docDB);
}
}
}
回归诱惑;
}
我希望这样做不会太粗鲁 老实说,我更喜欢以下功能:
public IEnumerable<T> GetAll<T>()
{
List<T> list = new List<T>();
RavenQueryStatistics statistics = new RavenQueryStatistics();
list.AddRange(_session.Query<T>().Statistics(out statistics));
if (statistics.TotalResults > 128)
{
int toTake = statistics.TotalResults - 128;
int taken = 128;
while (toTake > 0)
{
list.AddRange(_session.Query<T>().Skip(taken).Take(toTake > 1024 ? 1024 : toTake));
toTake -= 1024;
taken += 1024;
}
}
return list;
}
public IEnumerable GetAll()
{
列表=新列表();
RavenQueryStatistics=新的RavenQueryStatistics();
list.AddRange(_session.Query().Statistics(out Statistics));
如果(statistics.TotalResults>128)
{
int-toTake=statistics.TotalResults-128;
int=128;
while(toTake>0)
{
AddRange(_session.Query().Skip(Take.Take)(toTake>1024?1024:toTake));
toTake-=1024;
取+=1024;
}
}
退货清单;
}
[]的有轻微的扭曲。下面是一种将所有文档ID作为字符串列表获取的通用方法。请注意使用Advanced.LuceneQuery(idPropertyName)
、SelectFields(idPropertyName)
和GetProperty(idPropertyName)
使事物变得通用。默认设置假定“Id”
是给定
上的有效属性(99.999%的情况下应该是这样)。如果您有一些其他属性作为Id
,您也可以将其传入
公共静态列表getAllID(DocumentStore docDB,字符串idPropertyName=“Id”){
返回getAllidFrom(0,new List(),docDB,idPropertyName);
}
公共静态列表getAllidFrom(int startFrom、列表列表、DocumentStore docDB、字符串idPropertyName){
var allUsers=列表;
使用(var session=docDB.OpenSession())
{
int queryCount=0;
int start=startFrom;
while(true)
{
var current=session.Advanced.LuceneQuery().Take(1024).Skip(start).SelectFields(idPropertyName).ToList();
查询计数+=1;
如果(current.Count==0)
打破
开始+=当前的计数;
AddRange(current.Select(t=>(t.GetType().GetProperty(idPropertyName).GetValue(t,null)).ToString());
如果(查询计数>=28)
{
返回GetAllidFrom(start、allUsers、docDB、idPropertyName);
}
}
}
回归诱惑;
}
使用BulkInsert
会话在RavenDb中发出PatchRequest
时,我在何处/如何使用此选项的一个示例。在某些情况下,我可能有数十万个文档,无法在内存中加载所有文档,只是为了重新迭代它们以进行修补操作。。。因此,只需将其字符串ID加载到Patch
命令中
void PatchRavenDocs()
{
var store = new DocumentStore
{
Url = "http://localhost:8080",
DefaultDatabase = "SoMeDaTaBaSeNaMe"
};
store.Initialize();
// >>>here is where I get all the doc IDs for a given type<<<
var allIds = getAllIds<SoMeDoCuMeNtTyPe>(store);
// create a new patch to ADD a new int property to my documents
var patches = new[]{ new PatchRequest { Type = PatchCommandType.Set, Name = "SoMeNeWPrOpeRtY" ,Value = 0 }};
using (var s = store.BulkInsert()){
int cntr = 0;
Console.WriteLine("ID Count " + allIds.Count);
foreach(string id in allIds)
{
// apply the patch to my document
s.DatabaseCommands.Patch(id, patches);
// spit out a record every 2048 rows as a basic sanity check
if ((cntr++ % 2048) == 0)
Console.WriteLine(cntr + " " + id);
}
}
}
void PatchRavenDocs()
{
var存储=新文档存储
{
Url=”http://localhost:8080",
DefaultDatabase=“SoMeDaTaBaSeNaMe”
};
store.Initialize();
//>>>这里是我获取给定类型的所有文档ID的地方这个问题是在RavenDB中提供此功能之前发布的,但是如果其他人现在发现了这个问题
鼓励您这样做的方法是通过。RavenDB客户端对流进行批处理,以便自动“分页”服务器的请求/响应。如果您选择使用流API,则客户端会假定您“知道自己在做什么”,并且不会检查用于常规查询的128/1024/30限制
var query = session.Query<User>();
using (var enumerator = session.Advanced.Stream(query)) {
while (enumerator.MoveNext()) {
allUsers.Add(enumerator.Current.Document);
}
}
var count = allUsers.Count;
var query=session.query();
使用(var枚举器=session.Advanced.Stream(查询)){
while(枚举数.MoveNext()){
添加(枚举器.Current.Document);
}
}
var count=alluser.count;
提示:虽然这是解决问题的一种受鼓励的方法……但作为一般规则,最好从一开始就避免这种情况。如果有一百万条记录怎么办?那alluser
列表将变得巨大。也许可以先进行索引或转换,以过滤出您实际需要向用户/进程显示的数据这是为了报告?也许RavenDB应该自动导出到
public List<string> GetAllIds<T>()
{
var allIds = new List<string>();
IDocumentSession session = null;
try
{
session = documentStore.OpenSession();
int queryCount = 0;
int start = 0;
while (true)
{
var current = session.Advanced.DocumentQuery<T>()
.Take(1024)
.Skip(start)
.SelectFields<string>("__document_id")
.AddOrder("__document_id")
.ToList();
if (current.Count == 0)
break;
allIds.AddRange(current);
queryCount += 1;
start += current.Count;
if (queryCount == 30)
{
queryCount = 0;
session.Dispose();
session = documentStore.OpenSession();
}
}
}
finally
{
if (session != null)
{
session.Dispose();
}
}
return allIds;
}