首页 文章

RavenDB中的Map / reduce会抛出InvalidOperationException

提问于
浏览
3

我在使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 回答

  • 1

    Micha,这个bug现在已经修好了 . 它位于构建601中 . 要了解如何实际实现索引,请查看此测试:https://github.com/ayende/ravendb/blob/master/Raven.Tests/Bugs/MapRedue/TreeWithChildrenCount.cs

  • 1

    问题很简单,Map函数必须返回一个匿名类型(它现在不会这样做) . 此外,该匿名类型必须具有与您已定义为索引结果的类相同的属性 .

    我不知道如何更好地描述它,但根据经验,可以说 Map 功能必须始终以 select new { YourPropertyName = propValue } 结尾

  • 0

    我没有方便的raven实例,但尝试用ParentId = -1替换ParentId =(string)null,看看是否有帮助 . 尝试在我的索引中分配空值时遇到了一些问题 . 显然,这并不能解决问题,但可能有助于识别问题 .

相关问题