【问题标题】:RavenDB MultiMap IndexRavenDB 多图索引
【发布时间】:2012-04-28 15:38:20
【问题描述】:

我是 RavenDB 的新手。我正在尝试使用多地图索引功能,但我不确定它是否是解决我的问题的最佳方法。所以我有三个文件:Unit、Car、People。

汽车文档如下所示:

{
 Id: "cars/123",
 PersonId: "people/1235",
 UnitId: "units/4321",
 Make: "Toyota",
 Model: "Prius"
}

人物文档如下所示:

{
   Id: "people/1235",
   FirstName: "test",
   LastName: "test"
}

和单位文档:

{
   Id: "units/4321",
   Address: "blah blah"
}

这是一个简略的例子,在我的真实应用中,字段要多得多,所以数据反规范化是我最后的手段。

我需要创建和索引将所有这三个文档合并到一个文档中。像这样的:

{
   CarId: "cars/123",
   PersonId: "people/1235",
   UnitId: "units/4321",
   Make: "Toyota",
   Model: "Prius"
   FirstName: "test",
   LastName: "test"
   Address: "blah blah"
}

// same unit different person owns a different car

{
   CarId: "cars/122",
   PersonId: "people/1236",
   UnitId: "units/4321",
   Make: "Toyota",
   Model: "4runner"
   FirstName: "test",
   LastName: "test"
   Address: "blah blah"
}

在关系数据库中,我只需要通过 id 对 People 和 Unit 表使用两个连接 我的汽车表将是一个聚合实体。

这是我拥有的索引定义:

 public class MyMultiIndex : AbstractMultiMapIndexCreationTask<JoinedDocument>
 {
    public MyMultiIndex()
    {
        // creating maps
        AddMap<Car>(cars => cars.Select(e => new { e.CarId, e.Make, e.Model, PersonId = e.PersonId, UnitId = e.UnitId, FirstName = (null)string, LastName = (null)string, Address = (nul)string }));
        AddMap<People>(people => people.Select(e => new { CarId = (string)null, Make = (string)null, Model = (string)null, PersonId = e.Id, UnitId = (null)string, FirstName = e.FirstName, LastName = e.LastName, Address = (nul)string }));
        AddMap<Unit>(people => people.Select(e => new { CarId = (string)null, Make = (string)null, Model = (string)null, PersonId = (null)string, UnitId = e.null, FirstName = (nul)string , LastName = (nul)string , Address = e.Address }));

        Reduce = results => from result in results
                            group result by result.CarId
                            into g
                            select new JoinedDocument
                            {
                                CarId = g.Key,
                                PersonId = g.First(e => e.CarId == g.Key).PersonId,
                                UnitId = g.First(e => e.CarId == g.Key).UnitId,
                                Model = g.First(e => e.CarId == g.Key).Model,
                                Make = g.First(e => e.CarId == g.Key).Make,

                                **// this never works. It is like result set does not contain anything with this personId. It looks like AddMap for people document did not work.**

                                FirstName = results.First(e => e.PersonId == g.First(ie => ie.CarId == g.Key).PersonId).FirstName,

                                **// this never works. It is like result set does not contain anything with this personId. It looks like AddMap for people document did not work.**

                                LastName = results.First(e => e.PersonId == g.First(ie => ie.CarId == g.Key).PersonId).LastName,

                                **// this never works. It is like result set does not contain anything with this personId. It looks like AddMap for unit document did not work.**

                                UnitAddress = results.First(e => e.UnitId == g.First(ie => ie.CarId == g.Key).UnitId).LastName,
                           };
        Index(map => map.Model, FieldIndexing.Analyzed);
        Index(map => map.Make, FieldIndexing.Analyzed);
        Index(map => map.LastName, FieldIndexing.Analyzed);
        Index(map => map.FirstName, FieldIndexing.Analyzed);
        Index(map => map.Make, FieldIndexing.Analyzed);
        Index(map => map.UnitAddress, FieldIndexing.Analyzed);
    }
 }

当 RavenDb 运行此索引时,我在尝试运行我提供的 Reduce 函数时看到错误。当我尝试匹配存在人名和姓氏的记录时,它会引发错误,单位也会发生同样的情况。

【问题讨论】:

标签: ravendb


【解决方案1】:

您似乎正在尝试将文档数据库与具有关系的对象模型相匹配。此博客可能会对您有所帮助:

Keeping a Domain Model Pure with RavenDB

请记住,这不是 RavenDB 的推荐用法,但有时它是必要的,这是处理它的好方法。

【讨论】:

  • 所以据我所知,去规范化将是这里最简单和推荐的方法?
  • 我想如果你想忠于 RavenDB,那么可以。
  • -1 这是一个非常脆弱的解决方案,作者谈到保持模型纯净但关系有意义忽略关系的意义正是导致使用 ORM 时出现的所有废话的原因.
  • 忽略关系的含义是什么意思?
  • @BobHorn 模型之间的关系本质上是有意义的。 List RelatedDocIds 与 List 的决定不是持久性决定,而是模型设计问题。这个决定有很多含义。该博客的作者声称他正在做的是如何保持他的模型“纯粹”,但这实际上是错误的。他让他的模型非常不纯洁。他没有在他的模型之间设计定义良好的事务边界,而是创建了一个完全依赖于持久性机制的解决方案。他创建了一个 RavenDB ORM,它是一种反模式。
【解决方案2】:

你能拥有一辆没有车主的汽车吗?还是没有居民的地址?如果在这两种情况下都是错误的,我会将汽车和单元建模为嵌入人体内。因此,人成为您的总根,要到达汽车或单位,您必须经过一个人。

【讨论】:

  • 是的,这基本上是我必须做的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-07-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多