嵌套,可变长度数组上的RavenDB Map/Reduce/Transform [英] RavenDB Map/Reduce/Transform on nested, variable-length arrays

查看:46
本文介绍了嵌套,可变长度数组上的RavenDB Map/Reduce/Transform的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是RavenDB的新手,到目前为止,我一直很喜欢它.我还有一个要为我的项目创建的索引.

I'm new to RavenDB, and am loving it so far. I have one remaining index to create for my project.

问题

我对调查有数千个答复(即"提交"),并且每个提交都有一系列针对特定问题的答案(即"答案"),并且每个答案都有一系列选择的选项(即"").

I have thousands of responses to surveys (i.e. "Submissions"), and each submission has an array of answers to specific questions (i.e. "Answers"), and each answer has an array of options that were selected (i.e. "Values").

这是单个 Submission 基本上的样子:

Here is what a single Submission basically looks like:

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

更多问题:我必须能够按SurveyId,LocationId,QuestionId,创建日期进行过滤.据我了解,这是在查询时完成的……我只需要确保转换结果中存在这些属性(或者是归约结果?还是两者兼有?).如果我是对的,那么这就不成问题了.

More Problem: I have to able to filter by SurveyId, LocationId, QuestionId, Creation Date. As I understand it, that's done at query time... I just need to make sure that these properties are present in the transformation result (or is it the reduce result? or both?). If I'm right, then this is less of an issue.

所需结果

每个调查的每个问题需要一个对象,该对象给出了每个选项的总和.希望这是不言自明的:

We need one object per question per survey that gives the sum of each option. Hopefully it's self explanatory:

[
    {
        SurveyId: 1,
        QuestionId: 1,
        NumResponses: 976,
        NumComments: 273,
        Values: {
            "1": 452, // option 1 selected 452 times
            "2": 392, // option 2 selected 392 times
            "4": 785  // option 4 selected 785 times
        }
    },
    {
        SurveyId: 1,
        QuestionId: 2,
        NumResponses: 921,
        NumComments: 46,
        Values: {
            "1": 325,
            "2": 843,
            "4": 119,
            "8": 346,
            "32": 524
        }
    },
    ...
]

我的尝试

我还没走的很远,我想

I didn't get very far, and I think this post is heading me down the right path, but it doesn't help me with the list of Values. I've searched and searched but can't find any direction for what do with a nested array like that. Here's that I have so far:

地图:

from submission in docs.Submissions
from answer in submission.Answers
where answer.WasSkipped != true && answer.Value != null
select new {
    SubmissionDate = submission["@metadata"]["Last-Modified"],
    SurveyId = submission.SurveyId,
    LocationId = submission.LocationId,
    QuestionId = answer.QuestionId,
    Value = answer.Value
}

减少:

??

变形:

from result in results
from answer in result.Answers
where answer.WasSkipped != true && answer.Value != null
select new {
    SubmissionDate = result["@metadata"]["Last-Modified"],
    SurveyId = result.SurveyId,
    LocationId = result.LocationId,
    QuestionId = answer.QuestionId,
    Value = answer.Value
}

对于它的价值,它托管在RavenHQ上.

For what it's worth, this is hosted on RavenHQ.

已经很长时间了,我一直在努力解决这个问题,而且做对了.非常感谢您帮助我达到要求的结果!

It's been so long that I've been working on this and can't get it right. Any help in getting me to the required result is very appreciated!

推荐答案

假设您的C#类如下:

public class Submission
{
    public int SurveyId { get; set; }
    public int LocationId { get; set; }
    public IList<Answer> Answers { get; set; }
}

public class Answer
{
    public int QuestionId { get; set; }
    public int[] Values { get; set; }
    public string Comment { get; set; }
}

如果您正在运行RavenDB 2.5.2637或更高版本,则现在可以使用字典结果类型:

If you are running RavenDB 2.5.2637 or higher, you can now use a dictionary result type:

public class Result
{
    public int SurveyId { get; set; }
    public int QuestionId { get; set; }
    public int NumResponses { get; set; }
    public int NumComments { get; set; }
    public Dictionary<int, int> Values { get; set; }
}

如果您运行的是更早的版本(包括2.0版),则将无法使用字典,但是可以使用 IList< KeyValuePair< int,int>>

If you are running anything earlier (including 2.0 releases), then you won't be able to use a dictionary, but you can use an IList<KeyValuePair<int,int>> instead.

这里是索引:

public class TestIndex : AbstractIndexCreationTask<Submission, Result>
{
    public TestIndex()
    {
        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,
                  Values = answer.Values.ToDictionary(x => x, x => 1)
                  //Values = answer.Values.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
                 {
                     g.Key.SurveyId,
                     g.Key.QuestionId,
                     NumResponses = g.Sum(x => x.NumResponses),
                     NumComments = g.Sum(x => x.NumComments),
                     Values = g.SelectMany(x => x.Values)
                               .GroupBy(x => x.Key)
                               .ToDictionary(x => x.Key, x => x.Sum(y => y.Value))
                               //.Select(x => new KeyValuePair<int, int>(x.Key, x.Sum(y => y.Value)))
                 };
    }
}

(不需要变换步骤.)

如果不能使用2.5.2637或更高版本,则将 .ToDictionary 行替换为正下方的注释行,并使用 IList< KeyValuePair< int,int>> 在结果类中.

If you can't use 2.5.2637 or higher, then replace the .ToDictionary lines with the commented lines just below them, and use an IList<KeyValuePair<int,int>> in the result class.

基于map/reduce的字典修复方法基于此问题,其中您的帖子有助于识别.谢谢!

The fix to allow dictionaries in the map/reduce was based on this issue which your post helped to identify. Thank you!

这篇关于嵌套,可变长度数组上的RavenDB Map/Reduce/Transform的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆