IList <T>в мультикарте / уменьшить результат? - PullRequest
0 голосов
/ 27 декабря 2011

Я борюсь с концепцией мультикарты / сокращения RavenDB и недавно задал этот вопрос о том, как правильно написать индекс мультикарты / сокращения.

Я получил простой индекс в этом вопросе, но когда я попытался сделать его немного сложнее, я не смог заставить его работать. Я хочу, чтобы результат индекса содержал список строк, т.е.:

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)
              };
    }
}

В основном я пытался установить для свойства Items значение по умолчанию (IList) при сопоставлении ChildDocuments и значению свойства Items в RootDocument. Это не работает, однако. Выдает сообщение об ошибке

Ошибка по запросу. Не удалось понять запрос:

- строка 2, столбец 285: недопустимый пример

- строка 2 столбец 324: не удается разобрать double .0.0

при загрузке индекса. Как мне обрабатывать списки в мультикарте / уменьшать индексы?

Ответы [ 2 ]

3 голосов
/ 27 декабря 2011

Не используйте 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 голосов
/ 27 декабря 2011

Дэвид, ты должен понимать, что RavenDB хранит свои индексы в Lucene.NET.Это означает, что в вашем индексе не может быть никакого сложного типа .net.

В вашем примере я предлагаю вам использовать простой string вместо IList<string>.Затем вы можете присоединиться к своим строковым элементам:

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
    });
...