Evgeni
Evgeni

Reputation: 3353

RavenDb: querying by a property in related entity

Either I'm having a mental block, or its not that straightforward.

I have 2 classes, something like that:

public class House
{
    public string Id { get; set; }
    public string City { get; set; }
    public string HouseNumber { get; set; }
}

public class Person
{
    public string Id { get; set; }
    public string HouseId { get; set; }
    public string Name { get; set; }
}

Now I want a list of all people living in a given city, in a flattened model ({City, HouseNumber, PersonName}).

I can't figure out a way on how to map that.. If I had a City in a Person class that would be easy, but I don't, and it doesn't make sense there, imo.

Help ?

Edit:

I came up with this index, which actually works with in-memory list, but Raven returns nothing :(

 public class PeopleLocations : AbstractMultiMapIndexCreationTask<PeopleLocations.EntryLocation>
    {
        public class PeopleLocation
        {
            public string PersonId { get; set; }
            public string HouseId { get; set; }
            public string City { get; set; }
        }


        public PeopleLocations()
        {
            this.AddMap<House>(venues => venues.Select(x => new
            {
                x.City,
                HouseId = x.Id,
                PersonId = (string)null
            }));

            this.AddMap<Person>(people => people.Select(x => new
            {
                City = (string)null,
                HouseId = x.HouseId,
                PersonId = x.Id
            }));

            this.Reduce = results => results.GroupBy(x => x.HouseId)
                .Select(x => new
                {
                    HouseId = x.Key,
                    People = x.Select(e => e.PersonId),
                    City = x.FirstOrDefault(y => y.City != null).City,
                })
            .SelectMany(x =>
                x.People.Select(person => new PeopleLocation
                {
                    PersonId = person,
                    HouseId = x.HouseId,
                    City = x.City,
                })
            )
            .Select(x => new { PersonId = x.PersonId, x.City, x.HouseId });
        }
    }

Upvotes: 0

Views: 98

Answers (1)

Matt Johnson-Pint
Matt Johnson-Pint

Reputation: 241890

You can do this with a MultiMap Index - but there's a great new feature in RavenDB 2.0 called Indexing Related Documents that is much easier.

Map = people => from person in people
                let house = LoadDocument<House>(person.HouseId)
                select new
                {
                    house.City,
                    house.HouseNumber,
                    PersonName = person.Name,
                }

Upvotes: 1

Related Questions