我在使map / reduce操作工作时遇到困难 . 我是C#的业余爱好者,所以可能部分是由于我缺乏lambda和linq的经验来彻底分析和理解导致错误的原因(什么是对象创建表达式) .
代码编译完美,但是在执行时抛出异常,我不明白哪个部分不正确 .
当我禁用reduce操作时,错误仍然存在,因此我认为它与Map部分有关 .
RavenDB版本是:RavenDB-Build-573
这是例外:System.InvalidOperationException:变量初始化程序选择必须具有带有对象创建表达式的lambda表达式
我为RavenDB提供了如下索引:
IndexCreation.CreateIndexes(typeof(FullTree).Assembly, store);
Entity对象是一个简单的类,具有int Id和int ParentId .
这是map / reduce部分:
public class FullTreeObject
{
public int Id { get; set; }
public int Count { get; set; }
public int ParentId { get; set; }
}
public class FullTree : AbstractIndexCreationTask<Entity,FullTreeObject>
{
public FullTree()
{
Map = entities => from entity in entities
let ids = new object[]
{
new { entity.Id, Count = 0,
entity.ParentId },
new { Id = entity.ParentId, Count
= 1, ParentId = (string)null}
}
from id in ids
select id;
Reduce = results => from result in results
group result by result.Id into g
let parent = g.FirstOrDefault(x =>
x.ParentId != null)
select new
{
Id = g.Key,
Count = g.Sum(x => x.Count),
ParentId = parent ==
(object)null ? (object)null : parent.ParentId
};
}
}
希望有人可以提供一些线索 . 提前致谢 .
为了对输入做出反应,我修改了map / reduce实现 . RavenDB需要map和reduce输出相同的类型,但说实话,这是不对的,因为我输出的是实体对象的值,而不是数组中获取的值 . 但我无法通过intellisense达到这些 Value .
索引是在RavenDB工作室中创建的,但没有返回任何结果,所以我可以假设我的实现有问题 .
public class FullTree : AbstractIndexCreationTask<Entity,FullTreeObject>
{
public FullTree()
{
Map = entities => from entity in entities
let ids = new object[]
{
new { entity.Id, Count = 0, entity.ParentId },
new { Id = entity.ParentId, Count = 1, ParentId = (string)null}
}
from id in ids
select new {
entity.Id,
Count = 1,
entity.ParentId
};
Reduce = results => from result in results
group result by result.Id into g
let parent = g.FirstOrDefault(x => x.ParentId != null)
select new
{
Id = g.Key,
Count = g.Sum(x => x.Count),
ParentId = parent == (object)null ? (object)null : parent.ParentId
};
}
}
Build 601更新:
public class FullTree : AbstractIndexCreationTask<Entity, FullTree.ReduceResult>
{
public class ReduceResult
{
public int Id { get; set; }
public int Count { get; set; }
public int ParentId { get; set; }
}
public FullTree()
{
Map = entities => from entity in entities
let items = new[]
{
new { Id = (int) entity.Id, Count = (int) 0, ParentId = (int) entity.ParentId },
new { Id = (int) entity.ParentId, Count = (int) 1, ParentId = (int) 0}
}
from item in items
select new {
Id = item.Id,
Count = item.Count,
ParentId = item.ParentId
};
Reduce = results => from result in results
group result by result.Id into g
let itemWithParent = g.FirstOrDefault(x => x.ParentId != 0)
select new
{
Id = g.Key,
Count = g.Sum(x => x.Count),
ParentId = (itemWithParent == null) ? (int)0 : itemWithParent.ParentId
};
}
}
返回错误:[WebException:远程服务器返回错误:(500)内部服务器错误 . ] System.Net.HttpWebRequest.GetResponse()6111651 Raven.Client.Connection.HttpJsonRequest.ReadStringInternal(Func`1 getResponse)在c:\构建\乌鸦\ Raven.Client.Lightweight \连接\ HttpJsonRequest.cs:231
[InvalidOperationException:{“Url”:“/ indexes / FullTree”,“Error”:“System.InvalidOperationException:无法理解查询:\ r \ n--第2行第55行:无效NewExpression \ r \ n--第2行col 91:无法解析double .0.0 \ r \ n--第2行col 183:无法解析double .0.0 \ r \ n--第2行col 275:无法解析double .0.0 \ r \ n \ r \ n位于Raven.Database.Linq.QueryParsingUtils.GetVariableDeclarationForLinqMethods(String query,Boolean requiresSelectNewAnonymousType)位于Raven的c:\ Builds \ raven-unstable \ Raven.Database \ Linq \ QueryParsingUtils.cs:第122行\ r \ n . Database.Linq.DynamicViewCompiler.TransformMapDefinitionFromLinqMethodSyntax(String query,String&entityName)位于c:\ Builds \ raven-unstable \ Raven.Database \ Linq \ DynamicViewCompiler.cs:第355行\ r \ n在Raven.Database.Linq.DynamicViewCompiler.HandleMapFunction (ConstructorDeclaration ctor,String map)在c:\ Build中的Raven.Database.Linq.DynamicViewCompiler.TransformQueryToClass()中的c:\ Builds \ raven-unstable \ Raven.Database \ Linq \ DynamicViewCompiler.cs:第132行\ r \ n在ds:\ Builds \ raven-unstable \ Raven.Database \ Linq DynamicViewCompiler.cs:第489行\ r \ n在Raven.Database.DocumentDatabase.PutIndex(字符串名称,IndexDefinition定义)中的c:\ Builds \ raven-unstable \ Raven.Database \ DocumentDatabase.cs:第717行\ r \ n at Raven.Database中的Raven.Database.Server.Responders.Index.Put(IHttpContext context,String index)在Raven.Database中的c:\ Builds \ raven-unstable \ Raven.Database \ Server \ Responders \ Index.cs:第72行\ r \ n .Server.Responders.Index.Respond(IHttpContext context)位于c:\ Builds \ raven-unstable \ Raven.Database \ Server \ Responders \ Index.cs:第49行\ r \ n在Raven.Database.Server.HttpServer.DispatchRequest中(IHttpContext ctx)位于c:\ Builds \ raven-unstable \ Raven.Database \ Server \ HttpServer.cs:第527行\ r \ n,位于c:\ Builds \中的Raven.Database.Server.HttpServer.HandleActualRequest(IHttpContext ctx) raven-unstable \ Raven.Database \ Server \ HttpServer.cs:line 303“}] Rave n.Client.Connection.HttpJsonRequest.ReadStringInternal(Func`1 getResponse)在c:\ Builds \ raven \ Raven.Client.Lightweight \ Connection \ HttpJsonRequest.cs:295
3 回答
Micha,这个bug现在已经修好了 . 它位于构建601中 . 要了解如何实际实现索引,请查看此测试:https://github.com/ayende/ravendb/blob/master/Raven.Tests/Bugs/MapRedue/TreeWithChildrenCount.cs
问题很简单,Map函数必须返回一个匿名类型(它现在不会这样做) . 此外,该匿名类型必须具有与您已定义为索引结果的类相同的属性 .
我不知道如何更好地描述它,但根据经验,可以说 Map 功能必须始终以
select new { YourPropertyName = propValue }
结尾我没有方便的raven实例,但尝试用ParentId = -1替换ParentId =(string)null,看看是否有帮助 . 尝试在我的索引中分配空值时遇到了一些问题 . 显然,这并不能解决问题,但可能有助于识别问题 .