1

次のサンプルクラスの静的インデックスを作成しようとしています。

public class Board {
...other assorted fields
List<dynamic> Messages {get; set;}
internal Board() {Messages = new List<dynamic>();}
}

インデックスは、特定の日付より古いメッセージを持つボードをフィルタリングするためのものです。目的は、今日期限が切れるメッセージに対して「更新」操作を実行し、それらのコンテンツを更新して、それらを永続化することです。インデックスは、計算コストが高くなる可能性があるため、すべてのクライアントのボードのすべてのメッセージをトラバースしないようにするために必要です。メッセージは、プロパティExpiryDateを含む基本クラスから継承するメッセージタイプのリストです。

次のようなインデックスを作成しようとすると、「式ツリーに動的操作が含まれていない可能性があります」というエラーが発生します。動的型はLinqクエリではうまく機能しないため、RavenDBでQuery()の代わりにLuceneQueriesを使用する必要があることを私は知っています。このインデックスを動的プロパティで機能させる方法はありますか?ありがとう!

 public class ScanBoardMessagesIndex : AbstractIndexCreationTask<Board>
  {
    public ScanBoardMessagesIndex () {
      Map = boards => from board in boards
                     where board.Messages.Any(msg => ((MessageItem) msg).ExpiryDate <= DateTime.UtcNow.Date)
                     select board;
    }
  }

編集:

既存のBoardドキュメントのメタデータclr-typeが、有効ではなくなったクラス名前空間に設定されていたため、レイヴンのシリアル化の問題が発生しました。私は移行プロジェクトを行っているので、先に進み、既存のドキュメントのメタデータclrタイプを変更するパッチを最初に発行してから、動的タイプではなくメッセージのリストに基本/抽象クラスを使用する新しいデータ構造に移行します。

4

1 に答える 1

1

Map / Reduceインデックスは、特定の要件に適しているようです。事実上、ボード内のメッセージの最も古い有効期限までにボードにクエリを実行できるようにする必要があります。これは集約操作であり、まさにMap/Reduceが解決するように設計されたものです。また、メッセージに基本クラスを使用すると、下位レベルのIndexDefinitionに頼ることなくインデックスを定義できます。

public class Message
{
    public DateTime ExpiryDate { get; set; }
}

public class Board
{
    public string Id { get; set; }
    public List<Message> Messages { get; set; }
}

public class OldestExpiryDateMessageInBoard : AbstractIndexCreationTask<Board, OldestExpiryDateMessageInBoard.Result>
{
    class Result
    {
        public string BoardId { get; set; }
        public DateTime OldestExpiryDate { get; set; }
    }

    public OldestExpiryDateMessageInBoard()
    {
        this.Map = boards => from board in boards
                             from message in board.Messages
                             select new
                             {
                                 BoardId = board.Id,
                                 OldestExpiryDate = message.ExpiryDate
                             };

        this.Reduce = results => from result in results
                                 group result by result.BoardId into g
                                 select new
                                 {
                                     BoardId = g.Key,
                                     OldestExpiryDate = g.Min(x => x.OldestExpiryDate)
                                 };
    }
}

次に、Lucene構文を使用してこのインデックスをクエリできます。

于 2012-10-15T22:19:49.470 に答える