过滤静态RavenDB map / reduce索引

时间:2013-07-16 20:46:52

标签: mapreduce ravendb

情景/背景

  • RavenHQ上的Raven 2.0
  • 网络应用,因此优先选择异步

我的申请是一项调查申请。每个Survey都有一个Questions数组;相反,每个Submission(个人对调查的回答)都有一个Answers数组。

我有一个静态索引,汇总所有答案,以便我可以根据答案显示图表(例如,每个调查的每个问题,每个选项选择了多少人)。这些数据用于渲染例如饼图。这个聚合索引(在this question中讨论)基本上为每个调查提供一个问题对象,每个选项都有总和。

问题

我想过滤这些汇总值。其中一些是微不足道的,因为它们是结果中的字段(例如,按SurveyIdQuestionId过滤)。但是,我还希望按提交日期(来自元数据)或LocationId过滤,这些是Submissions中的字段,但显然不在汇总结果中。

换句话说,我需要能够向Raven询问有关特定LocationId或本月的问题的结果。

以下是单个提交的基本外观:

{
  "SurveyId": 1,
  "LocationId": 1,
  "Answers": [
    {
      "QuestionId": 1,
      "Values": [2,8,32],
      "Comment": null
    },
    {
      "QuestionId": 2,
      "Values": [4],
      "Comment": "Lorem ipsum"
    },
    ...more answers...
  ]
}

目前,这是聚合结果:

public class Result
{
    public int SurveyId { get; set; } // 1
    public int QuestionId { get; set; } // 1
    public int NumResponses { get; set; } // 576
    public int NumComments { get; set; } // 265
    public IList<KeyValuePair<int,int>> Values { get; set; } // [{Key:1, Value:264}, {Key:2, Value:163}, Key:4, Value:391}, ...]
}

这是聚合索引:

Map = submissions => 
    from submission in submissions
    from answer in submission.Answers
    select new
    {
        submission.SurveyId,
        answer.QuestionId,
        NumResponses = 1,
        NumComments = answer.Comment == null ? 0 : 1,
        Value = answer.Value.Select(x => new KeyValuePair<int, int>(x, 1))
    };

Reduce = results => 
    from result in results
    group result by new { result.SurveyId, result.QuestionId }
        into g
        select new Result
        {
            SurveyId = g.Key.SurveyId,
            QuestionId = g.Key.QuestionId,
            NumResponses = g.Sum(x => x.NumResponses),
            NumComments = g.Sum(x => x.NumComments),
            Value = g.SelectMany(x => x.Value)
                        .GroupBy(x => x.Key)
                        .Select(x => new KeyValuePair<int, int>(x.Key, x.Sum(y => y.Value)))
        };

从概念上讲,我倾向于将这些过滤器“传递”到查询中,但从我所读到的内容来看,这是行不通的,因为索引值是异步索引(存储)而没有单独的提交日期或LocationIds

这是否意味着我需要创建所有答案的索引,然后让聚合索引查询这个新的AllAnswers索引,或者什么?我已经做了一点点搜索另一个索引查询,没有运气。或者这是字段用于什么?

感谢任何指导!

1 个答案:

答案 0 :(得分:4)

您目前使用SurveyIdQuestionId汇总所有数据的索引。如果您希望按日期或位置进行分类,则这些是新索引。您只需将您想要的字段添加到地图中,将它们包含在分组键中,然后在结果中传递它们。然后,您可以轻松地通过这些键进行查询。

如果有不同的分组键,则无法将其合并为单个索引。您必须有多个索引。例如,我可能会调用您Submission_TotalsBySurveyAndQuestion以上的索引,而另一个索引可能是Submission_TotalsBySurveyAndQuestionPerLocation

以这种方式思考 - 现在,您可以在查询中添加WhereOrderBy,与SurveyIdQuestionId相对 - 因为这些是分组索引中的键。如果您想按LocationId进行过滤或排序,则必须包含该内容。

一句谨慎,你说:

  

我还希望按提交日期(来自元数据)进行过滤

RavenDB在元数据中(默认情况下)为您提供的唯一日期是Last-Modified日期。对文档的任何编辑都将更新此内容。因此,如果提交日期对您很重要,那么您应该将其保存在您自己的财产中。