【问题标题】:IList<T> in multi map/reduce result?多映射/减少结果中的 IList<T>?
【发布时间】:2011-12-26 21:12:49
【问题描述】:

我正在为 RavenDB 的多映射/归约概念苦苦挣扎,最近向 this question 询问如何正确编写多映射/归约索引。

我得到了那个问题中的简单索引,但是当我试图让它更复杂一点时,我无法让它工作。我想要做的是让索引的结果包含一个字符串列表,即:

class RootDocument {
  public string Id { get; set; }
  public string Foo { get; set; }
  public string Bar { get; set; }
  public IList<string> Items { get; set; }
}

public class ChildDocument {
  public string Id { get; set; }
  public string RootId { get; set; }
  public int Value { get; set; }
}

class RootsByIdIndex: AbstractMultiMapIndexCreationTask<RootsByIdIndex.Result> {
  public class Result {
    public string Id { get; set; }
    public string Foo { get; set; }
    public string Bar { get; set; }
    public IList<string> Items { get; set; }
    public int Value { get; set; }
  }

  public RootsByIdIndex() {
    AddMap<ChildDocument>(
      children => from child in children
        select new {
          Id = child.RootId,
          Foo = (string)null,
          Bar = (string)null,
          Items = default(IList<string>),
          Value = child.Value
      });
      AddMap<RootDocument>(
        roots => from root in roots
          select new {
           Id = root.Id,
           Foo = root.Foo,
           Bar = root.Bar,
           Items = root.Items,
           Value = 0
        });
      Reduce = 
        results => from result in results
          group result by result.Id into g
            select new {
              Id = g.Key,
              Foo = g.Select(x => x.Foo).Where(x => x != null).FirstOrDefault(),
              Bar = g.Select(x => x.Bar).Where(x => x != null).FirstOrDefault(),
              Items = g.Select(x => x.Items).Where(
                x => x != default(IList<string>).FirstOrDefault(),
                Value = g.Sum(x => x.Value)
              };
    }
}

基本上,当映射 ChildDocuments 和 RootDocument 的 Items 属性的值时,我尝试将 Items 属性设置为 default(IList)。然而,这不起作用。它给出了错误信息

请求错误无法理解查询:

-- line 2 col 285: 无效的 Expr

-- line 2 col 324: Can't parse double .0.0

上传索引时。如何处理多 map/reduce 索引中的列表?

【问题讨论】:

    标签: c# mapreduce ravendb


    【解决方案1】:

    不要在索引中使用 List,而是使用数组。

    AddMap<ChildDocument>(
      children => from child in children
        select new {
          Id = child.RootId,
          Foo = (string)null,
          Bar = (string)null,
          Items = new string[0],
          Value = child.Value
      });
      AddMap<RootDocument>(
        roots => from root in roots
          select new {
           Id = root.Id,
           Foo = root.Foo,
           Bar = root.Bar,
           Items = root.Items,
           Value = 0
        });
    
    Reduce = 
        results => from result in results
          group result by result.Id into g
            select new {
              Id = g.Key,
              Foo = g.Select(x => x.Foo).Where(x => x != null).FirstOrDefault(),
              Bar = g.Select(x => x.Bar).Where(x => x != null).FirstOrDefault(),
              Items = g.SelectMany(x=>x.Items),
              Value = g.Sum(x => x.Value)
              };
    

    【讨论】:

      【解决方案2】:

      David,您需要了解 RavenDB 使用 Lucene.NET 存储其索引。这意味着,您的索引中不能有任何复杂的 .net 类型。

      在您的示例中,我建议您使用简单的string 而不是IList&lt;string&gt;。然后你可以加入你的字符串项目:

      AddMap<ChildDocument>(
        children => from child in children
          select new {
            Id = child.RootId,
            Foo = (string)null,
            Bar = (string)null,
            Items = (string)null,
            Value = child.Value
        });
        AddMap<RootDocument>(
          roots => from root in roots
            select new {
             Id = root.Id,
             Foo = root.Foo,
             Bar = root.Bar,
             Items = string.Join(";", root.Items),
             Value = 0
          });
      

      【讨论】:

      • 好的,我只是假设我可以索引我可以存储的任何内容(并且存储 IList 工作正常)。
      猜你喜欢
      • 2012-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多