2012-04-18 21 views
5

Soy nuevo en RavenDB. Intento utilizar una función de índice de múltiples mapas, aunque no estoy seguro de si es el mejor enfoque para mi problema. Entonces tengo tres documentos: Unidad, Coche, Gente.RavenDB MultiMap Index

documento coche tiene el siguiente aspecto:

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

documento La gente se ve así:

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

Y unidad doc:

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

Este es un ejemplo abreviado, en mi verdadera aplicación hay mucho más campos, por lo que la des-normalización de datos sería mi último recurso.

Necesito crear e indexar que tendrá todas estas tres instrucciones unidas en un solo documento. Algo como esto:

{ 
    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" 
} 

En una base de datos relacional me acaba de utilizar dos se une a las personas y las tablas de la unidad por IDS y mi mesa de coche sería una entidad agregada.

Aquí es la definición del índice que tengo:

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

Cuando se ejecuta este índice RavenDb veo errores cuando se está tratando de ejecutar la función Reducir he proporcionado. Arroja un error cuando intento hacer coincidir un registro donde existe el nombre y el apellido de la persona, lo mismo sucede con la unidad.

+0

Publicación cruzada con lista de correo: https://groups.google.com/forum/?fromgroups#!topic/ravendb/Uym2tkvMaH8 –

+3

[Esta publicación] (http://ayende.com/blog/156225/relational -searching-sucks-donrsquo-t-try-to-replicate-it) aborda esta pregunta directamente. –

Respuesta

1

Parece que intenta ajustar una base de datos de documentos con un modelo de objetos con relaciones. Este blog puede ayudarle a:

Keeping a Domain Model Pure with RavenDB

Tenga en cuenta que este no es el uso recomendado de RavenDB, pero a veces es necesario, y esto es una buena manera de manejar la situación.

+0

Entonces, según tengo entendido, la denormificación sería el enfoque más fácil y recomendado aquí? – milagvoniduak

+1

Creo que si quieres permanecer fiel a RavenDB, entonces sí. –

+2

-1 esta es una solución terriblemente frágil, el autor habla de mantener puros los modelos, pero las relaciones tienen el significado de ignorar el significado de las relaciones, es exactamente lo que lleva a todas las porquerías que se caen cuando se trabaja con ORM. –

1

¿Puede tener un automóvil sin dueño? o una dirección sin residente? Si es falso en ambos casos, modelaría el automóvil y la unidad para que se incrustan dentro de una persona. Entonces la persona se convierte en su raíz agregada y para llegar a un automóvil o unidad debe pasar por una persona.

+0

Sí, eso fue esencialmente lo que tuve que hacer. – milagvoniduak