RavenDB多映射索引

5
我是一名RavenDB新手,我正在尝试使用多重映射索引功能,但我不确定它是否是解决我的问题的最佳方法。所以我有三个文档:Unit、Car、People。
Car文档如下:
{
 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使用两个连接,并且我的汽车表将是一个聚合实体。
这里是我拥有的索引定义:
 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函数时出现错误。当我尝试匹配一个人名和姓氏都存在的记录时,它会抛出错误,单位也是如此。

与邮件列表交叉发布: https://groups.google.com/forum/?fromgroups#!topic/ravendb/Uym2tkvMaH8 - Daniel Lang
3
这篇文章直接回答了这个问题。 - Sam Holder
2个回答

1

看起来你正在尝试将一个具有关系的对象模型与文档数据库相匹配。这篇博客可能会对你有所帮助:

使用RavenDB保持领域模型的纯净

请记住,这不是RavenDB的推荐用法,但有时候是必要的,而这是一个很好的处理方法。


1
我认为如果你想忠实于RavenDB,那么是的。 - Bob Horn
2
-1 这是一个非常脆弱的解决方案,作者谈到保持模型的纯粹性,但关系具有意义,忽略关系的意义正是导致在使用ORM时出现所有问题的原因。 - Chris Marisic
忽略关系的意义是什么意思? - Bob Horn
@BobHorn 模型之间的关系本质上具有意义。List<string> RelatedDocIds 与 List<RelatedDoc> 的决定不是持久性决策,而是模型设计问题。这个决定有很多含义。那篇博客的作者声称他所做的事情在某种程度上保持了他的模型的“纯洁性”,但实际上这是错误的。他使他的模型变得非常不纯。他没有设计出明确定义的事务边界,而是创建了一个完全依赖于持久性机制的解决方案。他创建了一个反模式的 RavenDB ORM。 - Chris Marisic
那么,您建议为了保持域实体之间的关系,但同时将它们存储在RavenDB中,应该采取什么措施? - Bob Horn
显示剩余2条评论

1

你能拥有一辆没有车主的汽车吗?或者一个没有居民的地址吗?如果在这两种情况下都是不可能的,那么我会将汽车和单元建模为嵌入到一个人内部。因此,这个人成为你的聚合根,要想得到一辆车或一个单元,你必须通过这个人。


是的,那基本上就是我要做的事情。 - milagvoniduak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接