2016-09-27 11 views
0

データ: コレクションには監査レコードのリストが含まれています。コレクションから最後に変更されたアイテムを返したいとします。例えばMongoDB C#Driver - 最後に変更された行のみを返します

Audit Records

だから、クエリのみ監査1235年と1237年を返す必要があります。

次のステートメントはMongo Shellで動作し、データをミリ秒単位で返します。IdだけでなくCollectionアイテム全体を返す方法も理解する必要があります。

db.Forms.aggregate(
{ $group: { _id: "$Id", lastModifiedId: { $last: "$_id" } } } 
) 

ただし、これをC#ドライバの構文に変換する必要があります。

私は現時点で以下のことをしていますが、動作しておらず、より良い用語がないために奇妙なデータを返します(ステートメントの下のscreencapを参照)。

var results = collection.Aggregate() 
.Group(new BsonDocument { { "_id", "$Id" }, { "lastModifiedId", new BsonDocument("$last", "_id") } }) 
.ToListAsync().Result.ToList(); 

Results

私の現在のソリューションは、バックフルコレクションを取得し、(リストがいっぱいコレクションです)最新のレコードを取得するには、拡張メソッドを介してそれを実行します:

var lastModifiedOnlyList = 
from listItem in list.OrderByDescending(_ => _.AuditId) 
group listItem by listItem.Id into grp 
select grp.OrderByDescending(listItem => listItem.AuditId) 
.FirstOrDefault(); 

ながらこのコードは機能しますが、コレクションから返されるデータの量が非常に少ないために非常に遅いので、get/findコレクションの一部としてリスト上でグループ化する必要があります。

追加情報を提供できるかどうか教えてください。

アップデート:私はそれを解決し得ることができたアクセルの助けを借りて:

var pipeline = new[] { new BsonDocument { { "$group", new BsonDocument { { "_id", "$Id" }, { "LastAuditId", new BsonDocument { { "$last", "$_id" } } } } } } }; 
var lastAuditIds = collection.Aggregate<Audit>(pipeline).ToListAsync().Result.ToList().Select(_=>_.LastAuditId); 

私は私の投影が同様に働いて、バックコレクションアイテムを取得するためのIDを使用した後に、それは自分の方法だと移動し、 :

var forLastAuditIds = ForLastAuditIds(collection); 

var limitedList = (
       projection != null 
        ? collection.Find(forLastAuditIds & filter, new FindOptions()).Project(projection) 
        : collection.Find(forLastAuditIds & filter, new FindOptions()) 
      ).ToListAsync().Result.ToList(); 

"filter"は、ExpressionまたはBsonDocumentのいずれかです。パフォーマンスは素晴らしいです - すべての事のための副次的なものです。助けてくれてありがとう、Axel!

答えて

1

は、私はあなたが余分なのOrderByをやっていると思うが、これは実行する必要があります。

var lastModifiedOnlyList = 
from listItem in list 
group listItem by listItem.Id into grp 
select grp.OrderByDescending(listItem => listItem.AuditId) 
.FirstOrDefault(); 

EDIT:

は、クエリのパフォーマンスを得るためにあなたが異なっ集計関数を使用できます。

var match = new BsonDocument 
{ 
    { 
     "$group", 
     new BsonDocument 
      { 
       { "_id", "$Id" }, 
       { "lastModifiedId", new BsonDocument 
        { 
         { 
          "$last", "$_id" 
         } 
        }} 
      } 
    } 
}; 

var pipeline = new[] { match }; 
var result = collection.Aggregate(pipeline); 

これはMongo Shellのクエリと同等でなければなりません。

+0

こんにちはアクセル、情報ありがとうございます。私はあなたの提案で自分のコードを更新しましたが、これまで少し改善されていましたが、かなり長い時間がかかっていましたので、グループにコレクションを移動する必要は今のやり方とは異なります。このグループでは遅くなるわけではありません。コレクションは現在、戻ってくるのに時間がかかります。e collection.Find(filter、new FindOptions()) –

+0

@JohannMarx私は答えを編集しました。それがあなたのために働くかどうか確認してください。 –

+0

アクセル、そのトリックをした、ありがとう! :)私は今IDと最新の監査IDを取得しています(Mongo Shellのクエリごとに)、私が今必要とするのは、Collectionアイテム全体を取得することだけです。つまり、そのAudit IDの対応するForm。 それは素敵で速いです! :) –

関連する問題