首页 文章

具有动态字段的文档上的RavenDB静态索引

提问于
浏览
1

我正在尝试为以下示例类创建静态索引:

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

该索引用于过滤具有比特定日期更早的消息的板 . 目的是对今天到期的消息执行“更新”操作,更新其内容并将其保留 . 需要索引以避免遍历所有客户端的板的所有消息,因为这可能是计算上昂贵的 . 消息是从包含属性ExpiryDate的基类继承的消息类型列表 .

尝试创建如下的索引会导致“表达式树可能不包含动态操作”错误 . 我知道动态类型不能很好地与Linq查询一起使用,因此需要在RavenDB中使用LuceneQueries而不是Query() . 有没有办法让这个索引与动态属性一起使用?谢谢!

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类型,然后将它们迁移到新的数据结构,该数据结构使用基类/抽象类来显示消息列表而不是动态类型 .

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语法查询此索引 .

相关问题