问题描述
我的工作是在后端使用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 Count
for each Code
type.
示例:搜索
使用上述数据作为指导,
Example:
Using the above data as a guideline,
有2711的文件在我的数据库与信息
的严重程度。结果
中有我与调试
严重性数据库410文件。
中有我与 local0到
设施数据库2574文档。结果
等...
我想要做的,当应用程序启动时产生相应的索引(或检查它们是否已经存在) ,但我甚至不知道从哪里开始。
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!