MultiMap Index Include problem #2851

55 views
Skip to first unread message

Alan Ciantar

unread,
Apr 16, 2014, 4:53:34 AM4/16/14
to rav...@googlegroups.com
Scenario : This might be a bit long so bear with me :(

Essentially I have 2 entities I want to be able to search on - being 'School' and 'Property'. Each of them inherit from 'BaseObject' which simply holds the Id.
Each of them has a linked City entity 'CityId'.
'City' also has 'RegionId' and 'CountryId'.

When I query the MultiMap, and load both entities, I want the linked 'RegionId' and 'CountryId' to be included in the query. (1 call)

    public class BaseObject
   
{
       
public string Id { get; set; }
   
}

   
public class Property : BaseObject
   
{
       
public string Name { get; set; }
       
public string CityId { get; set; }
   
}

   
public class School : BaseObject
   
{
       
public string Name { get; set; }
       
public string CityId { get; set; }
   
}

   
public class City : BaseObject
   
{
       
public string Name { get; set; }
       
public string RegionId { get; set; }
       
public string CountryId { get; set; }
   
}

   
public class Region : BaseObject
   
{
       
public string Name { get; set; }
       
public string CountryId { get; set; }
   
}

   
public class Country : BaseObject
   
{
       
public string Name { get; set; }
   
}

The MultiMapIndex
  public class MultiMapIndex : AbstractMultiMapIndexCreationTask<BaseObject>
   
{
       
public MultiMapIndex()
       
{
           
AddMap<School>(schools => from school in schools
                                      let city
= LoadDocument<City>(school.CityId)
                                     
select new
                                     
{
                                         
Id = school.Id,
                                         
Name = school.Name,
                                         
CityId = city.Id,
                                         
RegionId = city.RegionId,
                                         
CountryId = city.CountryId
                                     
});


           
AddMap<Property>(properties => from property in properties
                                           let city
= LoadDocument<City>(property.CityId)
                                           
select new
                                           
{
                                               
Id = property.Id,
                                               
Name = property.Name,
                                               
CityId = city.Id,
                                               
RegionId = city.RegionId,
                                               
CountryId = city.CountryId
                                           
});


           
Store("RegionId", FieldStorage.Yes);
       
}


The failing test:
  using (var session = store.OpenSession())
               
{
                   
var result = session.Query<BaseObject, MultiMapIndex>()
                       
.Customize(customization => customization.WaitForNonStaleResultsAsOfNow())
                       
.Include(x => ((School)x).CityId)
                     
.Customize(x =>
                     
{
                         
var luceneQuery = (IDocumentQuery<BaseObject>)x;
                          luceneQuery
.Include("RegionId");
                     
})
                       
.ToList();


                   
Assert.That(result[0].Id == _school.Id);
                   
Assert.That(result[1].Id == _property.Id);


                   
Assert.That(session.Advanced.NumberOfRequests == 1); // Just to make sure


                   
var city = session.Load<City>(_school.CityId);
                   
Assert.That(session.Advanced.NumberOfRequests == 1); // Should of remained 1.  <------- This passes


                   
var region = session.Load<Region>(city.RegionId);
                   
Assert.That(session.Advanced.NumberOfRequests == 1); // Should of remained 1.  <-------- This fails


               
}

I beleive I asked a similar question to this earlier (just not a multimap) and was told simply setting 'Store("RegionId", FieldStorage.Yes);' would work but it doesn't in the above ^.

To fix the above issue (for non-MultiMaps) I used a transformer which works ok, but I'm not sure how to create a Transformer for the above MultiMap ?


Attached test.
CanStoreIndexProperties.cs

Alan Ciantar

unread,
Apr 16, 2014, 4:54:16 AM4/16/14
to rav...@googlegroups.com
1) Should the Store() work for my problem?
2) Is there a way to create a Transformer for MultiMap?

Oren Eini (Ayende Rahien)

unread,
Apr 16, 2014, 9:07:36 AM4/16/14
to ravendb
The problem is that you are trying to do an include on a property that you didn't project.
Include works only on the things that you are actually getting.

You need to change the index to be:

public class MultiMapIndex : AbstractMultiMapIndexCreationTask<MultiMapIndex.Result>
{
public class Result
{
public string Id { get; set; }
public string RegionId { get; set; }
public string CityId { get; set; }
}

public MultiMapIndex()
{
AddMap<School>(schools => from school in schools
 let city = LoadDocument<City>(school.CityId)
 select new
 {
 Id = school.Id,
 Name = school.Name,
 CityId = city.Id,
 RegionId = city.RegionId,
 CountryId = city.CountryId
 });

AddMap<Property>(properties => from property in properties
  let city = LoadDocument<City>(property.CityId)
  select new
  {
  Id = property.Id,
  Name = property.Name,
  CityId = city.Id,
  RegionId = city.RegionId,
  CountryId = city.CountryId
  });

Store(x => x.RegionId, FieldStorage.Yes);
Store(x => x.CityId, FieldStorage.Yes);
Store(x => x.Id, FieldStorage.Yes);
}
}


And then your query will look like:

var result = session.Query<MultiMapIndex.Result, MultiMapIndex>()
.Customize(customization => customization.WaitForNonStaleResultsAsOfNow())
.Include(x => x.CityId)
.Include(x => x.RegionId)
.Include(x => x.Id)
.ProjectFromIndexFieldsInto<MultiMapIndex.Result>()
.ToList();




Oren Eini

CEO

Mobile: + 972-52-548-6969

Office:  + 972-4-674-7811

Fax:      + 972-153-4622-7811





--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply all
Reply to author
Forward
0 new messages