Индекс MultiMap RavenDB

Я новичок в 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"
}

В реляционной базе данных я бы просто использовал два соединения с таблицами People и Unit по идентификаторам, и моя таблица car была бы совокупной сущностью.

Вот определение индекса, которое у меня есть:

 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 запускает этот индекс, я вижу ошибки при попытке запустить предоставленную мной функцию сокращения. Выдает ошибку, когда я пытаюсь сопоставить запись, в которой существуют имя и фамилия человека, то же самое происходит с устройством.


person milagvoniduak    schedule 18.04.2012    source источник
comment
Кросс-пост со списком рассылки: groups.google.com/forum/? fromgroups#!topic/ravendb/Uym2tkvMaH8   -  person Daniel Lang    schedule 20.04.2012
comment
Это сообщение посвящено этому вопрос напрямую.   -  person Sam Holder    schedule 27.04.2012


Ответы (2)


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

Поддержание чистоты модели домена с помощью RavenDB

Имейте в виду, что это не рекомендуемое использование RavenDB, но иногда это необходимо, и это хороший способ справиться с этим.

person Bob Horn    schedule 19.04.2012
comment
Насколько я понимаю, денормализация будет самым простым и рекомендуемым подходом? - person milagvoniduak; 19.04.2012
comment
Я думаю, если вы хотите оставаться верным RavenDB, то да. - person Bob Horn; 19.04.2012
comment
-1 это жутко ломкое решение, автор говорит о сохранении моделей в чистоте, но отношения имеют смысл игнорировать смысл отношений — это как раз то, что приводит ко всей той хрени, которая вываливается при работе с ORM. - person Chris Marisic; 03.05.2012
comment
Что вы подразумеваете под игнорированием смысла отношений? - person Bob Horn; 03.05.2012
comment
Отношения @BobHorn между моделями по своей сути имеют смысл. Решение List‹string› RelatedDocIds vs List‹RelatedDoc› не является решением о сохранении, это проблема дизайна модели. Это решение имеет множество последствий. Автор этого блога утверждает, что то, что он делает, каким-то образом поддерживает чистоту своих моделей, но на самом деле это ложь. Он сделал свои модели очень нечистыми. Вместо разработки четко определенных транзакционных границ между своими моделями он вместо этого создал решение, которое полностью зависит от механизма постоянства. Он создал ORM RavenDB, который является антипаттерном. - person Chris Marisic; 04.05.2012
comment
Итак, что бы вы предложили, чтобы объекты домена имели отношения, но сохраняли их с RavenDB? - person Bob Horn; 04.05.2012
comment
Крис Марисич, я склонен с вами согласиться. В этом случае дизайн модели навязывается RavenDB ORM, что не очень хорошо. Но всегда есть чем пожертвовать, используя любую из ОРМС. Не идеальный мир. - person milagvoniduak; 21.05.2012

Можно ли иметь машину без хозяина? или адрес без резидента? Если это ложно в обоих случаях, я бы смоделировал машину и устройство, которые будут встроены в человека. Таким образом, человек становится вашим совокупным корнем, и чтобы добраться до машины или подразделения, вы должны пройти через человека.

person afif    schedule 28.04.2012
comment
Да, это было в основном то, что я должен был сделать. - person milagvoniduak; 21.05.2012