いくつかの作業項目を表す一連のドキュメントがあります。
public class WorkItem
{
public string Id {get;set;
public string DocumentId { get; set; }
public string FieldId { get; set; }
public bool IsValidated { get; set; }
}
public class ExtractionUser
{
public string Id {get;set;}
public string Name {get;set;}
public string[] AssignedFields {get;set;}
}
ユーザーは一連の FieldId にアクセスできます。この一連のフィールドに基づいて WorkItem をクエリし、ドキュメントごとにステータスを取得する必要があります。
public class UserWorkItems
{
public string DocumentId { get; set; }
public int Validated { get; set; }
public int Total { get; set; }
}
私が後にしているクエリは次のとおりです。
using (var session = RavenDb.OpenSession())
{
string[] userFields = session.Load<User>("users/1").Fields;
session.Query<WorkItem>()
.Where(w => w.FieldId.In(userFields))
.GroupBy(w => w.DocumentId)
.Select(g => new
{
DocumentId = g.Key,
Validated = g.Where(w => w.IsValidated).Count(),
Total = g.Count()
}).Skip(page * perPage).Take(perPage)
.ToArray();
}
Map/Reduce インデックスを作成しようとしましたが、主な問題は、カウントされるプロパティであるため、Reduce 出力に含まれない FieldId にフィルターを適用できるようにする必要があることでした。
また、クエリ部分の FieldId と TransformResults で単純な Map インデックスを実行して GroupBy を実行しようとしましたが、TransformResults の前にページングが適用されるため、グループ化前のドキュメントがページと合計に反映されますが、これは良くありません。
次に、ユーザーとそのフィールド コレクションをマップし、ワークアイテムとフィールドをマップするマルチ マップ インデックスを使用して、結果を希望どおりに縮小しようとしました。インデックス定義で要点を作成しました。reduce 部分には、group by フィールド、複数の SelectMany、および最後の GroupBy と Select が含まれます。インデックスは raven によって受け入れられましたが、結果が返されません。実際にデバッグする方法がわからないので、マルチ マップ インデックスに少し行き詰まっています。
最終的に、私の問題は「削減された」フィールドでクエリを実行する方法に削減される可能性があると思います。
このような機能を実現する方法はありますか? Map/MultiMap/Reduce/TransformResults 以外に探索できるオプションはありますか?
更新: Ayende の Map Reduce の投稿を読んでいるときに、mapreduce に間違ってアプローチしていることに気付きました。まだ解決策を探しています...
UPDATE 2:もう少し調査した後、私はやりたいことのように見えるがデータを返さないこのインデックスになりました(インデックスはスタジオで直接定義されました):
地図:
from user in docs
where user["@metadata"]["Raven-Entity-Name"] == "ExtractionUsers"
from field in user.AssignedFields
from item in docs
where item["@metadata"]["Raven-Entity-Name"] == "WorkItems" && item.FieldId == field
select new {
UserId = user.Id,
DocumentId = item.DocumentId,
Validated = item.Status=="Validated"? 1: 0,
Count = 1
}
減らす:
from r in results
group r by new { r.UserId , r.DocumentId } into g
select new {
UserId = g.Key.UserId,
DocumentId = g.Key.DocumentId,
Validated = g.Sum(d => d.Validated),
Count = g.Sum(d => d.Count),
}
アイデアは、すべてのドキュメントをインデックスにマップし、Users から Fields および WorkItems にリンクしようとすることです。