私はこの質問の変形が以前に(私によってさえ)尋ねられたことを知っています、しかし私はまだこれについて1つか2つのことを理解していません...
これを行うことで、128のデフォルト設定よりも多くのドキュメントを取得できることを理解していました。
session.Advanced.MaxNumberOfRequestsPerSession = int.MaxValue;
また、WHERE句はFuncではなくExpressionTreeである必要があるため、EnumerableではなくQueryableとして扱われることを学びました。だから私はこれがうまくいくはずだと思った:
public static List<T> GetObjectList<T>(Expression<Func<T, bool>> whereClause)
{
using (IDocumentSession session = GetRavenSession())
{
return session.Query<T>().Where(whereClause).ToList();
}
}
ただし、128個のドキュメントしか返されません。どうして?
上記のメソッドを呼び出すコードは次のとおりです。
RavenDataAccessComponent.GetObjectList<Ccm>(x => x.TimeStamp > lastReadTime);
Take(n)を追加すると、必要な数のドキュメントを取得できます。たとえば、これは200個のドキュメントを返します。
return session.Query<T>().Where(whereClause).Take(200).ToList();
これらすべてに基づいて、何千ものドキュメントを取得する適切な方法は、MaxNumberOfRequestsPerSessionを設定し、クエリでTake()を使用することであるように思われます。そうですか?そうでない場合、どのようにすべきそれは行われますか?
私のアプリでは、何千ものドキュメント(データがほとんどない)を取得する必要があります。これらのドキュメントをメモリに保存し、グラフのデータソースとして使用します。
**編集**
Take()でint.MaxValueを使用してみました:
return session.Query<T>().Where(whereClause).Take(int.MaxValue).ToList();
そして、それは1024を返します。 1024を超えるにはどうすればよいですか?
**編集2-データを示すサンプルドキュメント**
{
"Header_ID": 3525880,
"Sub_ID": "120403261139",
"TimeStamp": "2012-04-05T15:14:13.9870000",
"Equipment_ID": "PBG11A-CCM",
"AverageAbsorber1": "284.451",
"AverageAbsorber2": "108.442",
"AverageAbsorber3": "886.523",
"AverageAbsorber4": "176.773"
}
Take(n)
関数は、デフォルトで1024までしか提供しません。ただし、このデフォルトはRaven.Server.exe.config
で変更できます。
<add key="Raven/MaxPageSize" value="5000"/>
詳細については、以下を参照してください。 http://ravendb.net/docs/intro/safe-by-default
バージョン2.5以降、RavenDBにはストリーミングを可能にする「無制限の結果API」があることに注意してください。ドキュメントの例は、これを使用する方法を示しています。
var query = session.Query<User>("Users/ByActive").Where(x => x.Active);
using (var enumerator = session.Advanced.Stream(query))
{
while (enumerator.MoveNext())
{
User activeUser = enumerator.Current.Document;
}
}
標準のRavenDBクエリ、Lucenceクエリがサポートされており、非同期サポートもあります。
Take(n)関数は、デフォルトで1024までしか提供しません。ただし、Skip(n)と組み合わせて使用すると、すべてを取得できます。
var points = new List<T>();
var nextGroupOfPoints = new List<T>();
const int ElementTakeCount = 1024;
int i = 0;
int skipResults = 0;
do
{
nextGroupOfPoints = session.Query<T>().Statistics(out stats).Where(whereClause).Skip(i * ElementTakeCount + skipResults).Take(ElementTakeCount).ToList();
i++;
skipResults += stats.SkippedResults;
points = points.Concat(nextGroupOfPoints).ToList();
}
while (nextGroupOfPoints.Count == ElementTakeCount);
return points;
セッションごとのリクエスト数は、呼び出しごとに取得されるドキュメントの数とは別の概念です。セッションは短命であり、それらを介して発行される呼び出しはほとんどないと予想されます。
人間が消費するためにストアから10を超えるもの(デフォルトの128よりも少ないもの)を取得している場合は、何かが間違っているか、データストアからのドキュメントのトラック負荷とは異なる考え方が必要です。
RavenDBのインデックス作成は非常に洗練されています。インデックス作成に関する優れた記事 ここ およびファセット ここ 。
データ集計を実行する必要がある場合は、map/reduceインデックスを作成して、集計データを作成します。例:
インデックス:
from post in docs.Posts
select new { post.Author, Count = 1 }
from result in results
group result by result.Author into g
select new
{
Author = g.Key,
Count = g.Sum(x=>x.Count)
}
クエリ:
session.Query<AuthorPostStats>("Posts/ByUser/Count")(x=>x.Author)();
Stream
メソッドで事前定義されたインデックスを使用することもできます。インデックス付きフィールドにWhere句を使用できます。
_var query = session.Query<User, MyUserIndex>();
var query = session.Query<User, MyUserIndex>().Where(x => !x.IsDeleted);
using (var enumerator = session.Advanced.Stream<User>(query))
{
while (enumerator.MoveNext())
{
var user = enumerator.Current.Document;
// do something
}
}
_
インデックスの例:
_public class MyUserIndex: AbstractIndexCreationTask<User>
{
public MyUserIndex()
{
this.Map = users =>
from u in users
select new
{
u.IsDeleted,
u.Username,
};
}
}
_
ドキュメント: インデックスとは?セッション:クエリ:クエリ結果をストリーミングする方法?
重要な注意:Stream
メソッドはオブジェクトを追跡しません。このメソッドから取得したオブジェクトを変更した場合、SaveChanges()
は変更を認識しません。
その他の注意:使用するインデックスを指定しない場合、次の例外が発生する可能性があります。
InvalidOperationException:StreamQueryは、動的インデックスのクエリをサポートしていません。これは大きなデータセットで使用するように設計されており、Query()のように、15秒のインデックス作成後にすべてのデータセットを返すことはほとんどありません。