【问题标题】:RavenDB complex indexRavenDB 复杂索引
【发布时间】:2013-02-14 00:29:00
【问题描述】:

虽然我对使用 RavenDB 作为 OLTP 应用程序存储的想法感到非常兴奋,但我对 Linq/Map-Reduce 索引实现有点麻烦。

这就是我想要做的—— 我有文件-

Event {
   UserId:  "1",
   Location : "X",
   EventDate : "1/1/2010",
   EventType : "type A"
}
...
Event {
   UserId:  "2",
   Location : "Y",
   EventDate : "1/1/2011",
   EventType : "type B"
}

应该执行的操作查询/索引是

“在特定日期范围内为特定用户提供不同事件的计数,按位置、事件分组”

结果示例:

Location | Count(EventA) | Count(EventB) 
---------------------------------------
X        | 10            |     2
Y        |  4            |    22

我相信这应该是直截了当的。我可能只是错过了一些东西。

感谢您的帮助!

【问题讨论】:

    标签: map indexing group-by ravendb reduce


    【解决方案1】:

    您所问的是一个典型的举报案例。这是 RavenDB 不太适合的一件事 (http://ravendb.net/docs/server/bundles/index-replication)。您的问题类似于 SQL Server Analysis Services 中多维数据集的结构。

    这种情况下的问题是日期范围。如果范围是固定的,比如我想知道每个月的情况,你可以在索引中执行此操作,但如果范围是临时的,那么我相信在 Raven 中使用索引是不可能的,甚至可能不会查询,因为您必须在客户端进行分组,因此必须检索大量文档(远远超过 Raven 的默认 128)。

    但如果有人在我们省略日期范围的索引中按示例搜索多个组,那么遵循索引实现,其中结果按用户 ID、位置和事件类型分组可能是一种解决方案:

    public class Index : AbstractIndexCreationTask<Index.Result>
    {
        public class Result
        {
            public string UserId { get; set; }
            public string Location { get; set; }
            public string EventType { get; set; }
            public int Count { get; set; }
        }
    
        public Index()
        {
            Map = events => from e in events
                            select new Result
                            {
                                UserId = e.UserId,
                                Location = e.Location,
                                EventType = e.EventType,
                                Count = 1
                            };
    
            Reduce = results => from result in results
                                group result by new { result.UserId, result.Location, result.EventType }
                                    into g
                                    select new Result
                                    {
                                        UserId = g.Key.UserId,
                                        Location = g.Key.Location,
                                        EventType = g.Key.EventType,
                                        Count = g.Sum(x => x.Count)
                                    };
        }
    }
    

    这会给你这个结果

    UserId   | Location | EventType     | Count
    -------------------------------------------
    1        | X        | A             |     2
    1        | X        | B             |     4
    1        | Y        | A             |    22
    1        | Y        | B             |     6
    2        | X        | A             |     7
    2        | X        | B             |     3
    2        | Y        | A             |     9
    2        | Y        | B             |    16
    

    然后您可以查询该索引并对查询结果进行额外分组。

    【讨论】:

    • 好答案。你触及了问题的核心——你不能有一个任意的日期范围。如果您希望它们每天、每周、每月等进行分组,那么您可以。可以使用多个索引并将结果相交以使其感觉更加随意。我已经计划了一段时间了......
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多