如何正确地创建一个地图在C#/缩小指数RavenDB [英] How to properly create a Map/Reduce Index for RavenDB in C#

查看:175
本文介绍了如何正确地创建一个地图在C#/缩小指数RavenDB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的工作是在后端使用RavenDB的应用程序。这是利用乌鸦我第一次,我与地图挣扎/缩小。

I'm working on an app that uses RavenDB on the back end. It's my first time using Raven, and I'm struggling with Map/Reduce.

我一直的阅读文档的,但不幸的是我没有在这个过程中得到的任何地方。

I have been reading the doc's, but unfortunately I'm not getting anywhere in the process.

基本上我有成千上万的这样的文件。

Basically I have thousands of documents like this.

{
  .....
  "Severity": {
    "Code": 6,
    "Data": "Info"
  },
  "Facility": {
    "Code": 16,
    "Data": "Local Use 0 (local0)"
  },
  .....
}

和出来的,我需要与看起来像这样的输出单个查询。

And out of it, I need to make a single query with output that looks like this.

{"Severity": [
    {"Emergency":0},
    {"Alert":0},
    {"Critical":0},
    {"Error":0},
    {"Warning":0},
    {"Notice":0},
    {"Info":2711},
    {"Debug":410}
],
"Facility": [
    {"Kernel Messages":0},
    {"User-Level Messages":0},
    {"Mail System":0},
    {"System Daemons":0},
    {"Security/Authorization Messages":0},
    {"Internal Syslogd Messages":0},
    {"Line Printer Subsystem":2711},
    {"Network News Subsystem":410},
    ....
    {"Local Use 0 (local0)": 2574},
    ...
]}

由此,钥匙的严重性/设施阵列是上面的JSON数据的数据部分,并在严重的价值/设施阵列是文档计数每个代码键入

Whereby the "Key" in the Severity/Facility Array is the Data portion of the above json data, and the "value" in the Severity/Facility Array is the document Countfor each Code type.

示例:搜索
使用上述数据作为指导,

Example:
Using the above data as a guideline,

有2711的文件在我的数据库与信息的严重程度。结果
中有我与调试严重性数据库410文件。

中有我与 local0到设施数据库2574文档。结果
等...

There are 2711 documents in my database with an Info severity.
There are 410 documents in my database with a Debug severity.
There are 2574 documents in my database with a local0 facility.
etc...

我想要做的,当应用程序启动时产生相应的索引(或检查它们是否已经存在) ,但我甚至不知道从哪里开始。


What I'd like to do is generate the appropriate indexes when the app starts up (or check if they already exist), but I don't even know where to begin.

请注意:该应用程序需要生成索引,这是不够的,只是手动将其写入到RavenDB的Web UI

note: the app needs to generate the index, it's not enough to just manually write it into the RavenDB Web UI.

推荐答案

您需要将几种技术来实现这个结合,但它是相当可行的。

You will need to combine several techniques to achieve this, but it is quite doable.

下面是应该为你工作好指数

Here is an index that should work well for you.

public class MyIndex : AbstractMultiMapIndexCreationTask<MyIndex.ReduceResult>
{
    public class ReduceResult
    {
        public string Source { get; set; }
        public string Code { get; set; }
        public string Data { get; set; }
        public int Count { get; set; }
    }

    public MyIndex()
    {
        AddMap<MyDoc>(docs => from doc in docs
                              select new
                                     {
                                         Source = "Severity",
                                         doc.Severity.Code,
                                         doc.Severity.Data,
                                         Count = 1
                                     });

        AddMap<MyDoc>(docs => from doc in docs
                              select new
                                     {
                                         Source = "Facility",
                                         doc.Facility.Code,
                                         doc.Facility.Data,
                                         Count = 1
                                     });

        Reduce = results => from result in results
                            group result by new { result.Source, result.Code }
                            into g
                            select new
                            {
                                g.Key.Source,
                                g.Key.Code,
                                g.First().Data,
                                Count = g.Sum(x => x.Count)
                            };

        TransformResults = (database, results) =>
                           from result in results
                           group result by 0
                           into g
                           select new
                           {
                               Severity = g.Where(x => x.Source == "Severity")
                                           .ToDictionary(x => x.Data, x => x.Count),
                               Facility = g.Where(x => x.Source == "Facility")
                                           .ToDictionary(x => x.Data, x => x.Count)
                           };
    }
}

您还需要变换结果容器类:

You also need a container class for the transformed result:

public class MyDocCounts
{
    public IDictionary<string, int> Severity { get; set; }
    public IDictionary<string, int> Facility { get; set; }
}

您会质疑这样的:

var result = session.Query<MyIndex.ReduceResult, MyIndex>()
                    .As<MyDocCounts>()
                    .ToList().First();



.ToList()看起来是多余的,但它是必要的,因为我们是在变换分组。

The .ToList() may seem redundant, but it's necessary because we are grouping in the transform.

一个完整的单元测试的此处。它的输出是这样的:

A complete unit test is here. The output of which looks like this:

{
  "Severity": {
    "AAA": 20,
    "BBB": 20,
    "CCC": 20,
    "DDD": 20,
    "EEE": 20
  },
  "Facility": {
    "FFF": 20,
    "GGG": 20,
    "HHH": 20,
    "III": 20,
    "JJJ": 20
  }
}

这篇关于如何正确地创建一个地图在C#/缩小指数RavenDB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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