1

场景/上下文

  • RavenHQ 上的 Raven 2.0
  • Web 应用程序,因此首选异步

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

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

问题

我想过滤这些聚合值。其中一些是微不足道的,因为它们是结果中的字段(例如过滤器SurveyIdQuestionId)。但是,我还想按 Submission date (来自元数据)或 by 过滤LocationId,它们是 individual 中的字段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 索引,还是什么?我已经做了一些搜索以使一个索引查询另一个索引,但没有运气。或者这就是字段的用途?

任何指导表示赞赏!

4

1 回答 1

4

SurveyId您当前拥有的索引通过和将所有数据聚合在一起QuestionId。如果您希望按日期或位置对其进行细分,那么这些是新索引。您只需将所需的字段添加到地图中,将它们包含在分组键中,然后在结果中传递它们。然后您可以通过这些键轻松查询。

当您有不同的分组键时,您无法将其合并到单个索引中。你必须有多个索引。例如,我可能会调用您上面的索引Submission_TotalsBySurveyAndQuestion,而另一个索引可能是Submission_TotalsBySurveyAndQuestionPerLocation.

以这种方式考虑 - 现在,您可以在查询中包含一个WhereorOrderBy来反对SurveyIdor QuestionId- 因为它们是索引中的分组键。如果要过滤或排序LocationId,则必须包括在内。

提醒一句,你说:

我还想按提交日期过滤(来自元数据)

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

于 2013-07-16T21:01:35.930 回答