我很难让map/reduce操作正常工作。我是C#的爱好者,所以可能部分是因为我缺乏lambda和linq的经验,无法彻底分析和理解导致错误的原因(什么是对象创建表达式)。
代码编译得很好,但在执行时会引发异常,我不知道哪一部分不正确。
当我禁用reduce操作时,错误仍然存在,所以我认为它与地图部分。
RavenDB版本为:RavenDB-Build-573
这是异常:System.InvalidOperationException:Variable初始值设定项select必须具有带对象create的lambda表达式表达式
我为RavenDB提供了这样的索引:
IndexCreation.CreateIndexes(typeof(FullTree).Assembly, store);
Entity对象是一个简单的类,具有一个int Id和一个int ParentId。
这是地图/缩小部分:
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输出,但老实说,这不可能是正确的,因为我输出的是实体对象的值,而不是数组中获得的值。但我无法用智能来达到这些价值观。
索引是在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
};
}
}
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()+611651c:\Builds\Raven\Raven.Client.Lightweight\Connection\HttpJsonRequest.cs:231 中的Raven.Customer.Connection.HttpJsonRequest.ReadStringInternal(Func`1 getResponse)
[无效操作异常:{"Url":"/indexes/FullTree","错误":"System.InvalidOperationException:无法理解Raven.Database.Linq.QueryParsingUtils.GetVariableDeclarationForLinqMethods处的查询:\r\n-第2行第55列:无效NewExpression\r\n-第二行第91列:无法解析double.0.0\r\n-第2列第183列:无法分析double.0.2\r\n-第二列第275列:无法剖析double.0.0\r\n\r\n(字符串查询,布尔要求SelectNewAnonymousType)中的c:\Builds\raven不稳定\raven.Database\Linq\QueryParsingUtils:line122\r\n at raven.Database.Linq.DynamicViewCompiler.TransformMapDefinitionFromLinqMethodSyntax(字符串查询,字符串和实体名称)c: \Builds\raven不稳定\raven.Database\Linq\DynamicViewCompiler.cs:line 132\r\n在raven.Database.Linq.DynamicView Compiler.TransformQueryToClass()中的c:\Builds\raven-Database.Linq \Dynamic ViewCompiler.cs:line 97\r\n在raven.Database.Link.Dynamic View CompilerGeneratorInstance()中Raven.Builds\Raven不稳定\Raven.Database\DocumentDatabase.PutIndex(字符串名称,IndexDefinition定义),位于Raven.Database.Server.Responders.Index.Put(IHttpContext上下文,字符串索引),位于c:\Builds\Raven-Database\Server\Responders\Index.cs:line 72\r\n在c:\Builds\raven不稳定\raven.Database\Server\Responders\Index.cs:line 49\r\n at raven.Database.Server.HttpServer.DispatchRequest(IHttpContext ctx)中的c:\Builds\raven不稳定\ raven.DDatabase\Server\HttpServer.cs:line 527\r\n at raven。Database.Server.HttpServer.HandleActualRequest}]c:\Builds\Raven\Raven.Client.Lightweight\Connection\HttpJsonRequest.cs:295
Micha中的Raven.Customer.Connection.HttpJsonRequest.ReadStringInternal(Func`1 getResponse),该错误现已修复。它在601号楼。要了解如何实际实现所需的索引,请查看以下测试:https://github.com/ayende/ravendb/blob/master/Raven.Tests/Bugs/MapRedue/TreeWithChildrenCount.cs
问题只是Map函数必须返回一个匿名类型(目前还没有返回)。此外,该匿名类型必须与您定义为索引结果的类具有相同的属性。
我不知道如何更好地描述它,但根据经验,可以说map函数必须始终以select new { YourPropertyName = propValue }
我手头没有raven实例,但试着用ParentId=-1替换ParentId=(字符串)null,看看这是否有帮助。我在尝试像那样在索引中分配null时遇到了一些问题。显然,这并不能解决问题,但可能有助于识别问题