2013-01-14 65 views
2

我在RavenDB以下實體集合:RavenDB跨實體查詢匹配

public class EntityA 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public string[] Tags { get; set; } 
} 

public class EntityB 
{ 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public string[] Tags { get; set; } 
} 

共享的唯一的事情就是Tags集合:的EntityA標籤可能存在於EntityB,讓他們可能相交。

如何檢索每個EntityAEntityB相交的標記,其中EntityBName屬性等於給定值?

+0

你的標籤暗示你一直在尋找正確的地方 - 你已經有了哪些索引? – chris

+0

目前我在MultiMapIndexes,Transforms,Includes和LiveProjections中處於膝蓋深處 - 無法擺脫這種困境。解決方法是兩次到數據庫,但我寧願不要。 – Nick

回答

2

嗯,這是一個困難的。要做到這一點,你需要兩個級別的減少 - 一個由標籤擴大你的結果,另一個由ID將其摺疊回去。烏鴉沒有一個簡單的方法來做到這一點。

雖然使用變換,但您可以將其僞造。唯一的問題是您的結果集中有skipped items,因此請確保您知道how to deal with those

public class TestIndex : AbstractMultiMapIndexCreationTask<TestIndex.Result> 
{ 
    public class Result 
    { 
     public string[] Ids { get; set; } 
     public string Name { get; set; } 
     public string Tag { get; set; } 
    } 

    public TestIndex() 
    { 
     AddMap<EntityA>(entities => from a in entities 
            from tag in a.Tags.DefaultIfEmpty("_") 
            select new 
             { 
              Ids = new[] { a.Id }, 
              Name = (string) null, 
              Tag = tag 
             }); 

     AddMap<EntityB>(entities => from b in entities 
            from tag in b.Tags 
            select new 
             { 
              Ids = new string[0], 
              b.Name, 
              Tag = tag 
             }); 

     Reduce = results => from result in results 
          group result by result.Tag 
          into g 
          select new 
           { 
            Ids = g.SelectMany(x => x.Ids), 
            g.First(x => x.Name != null).Name, 
            Tag = g.Key 
           }; 

     TransformResults = (database, results) => 
          results.SelectMany(x => x.Ids) 
            .Distinct() 
            .Select(x => database.Load<EntityA>(x)); 
    } 
} 

也看到完整的單元測試here

還有一種方法,但我還沒有測試過。那將是使用Indexed Properties Bundle做第一遍,然後將這些結果映射到第二遍。我正在對此進行一般性的實驗,如果有效,我會用結果更新這個答案。

+0

超級馬特!做得好。要添加,在查詢索引時也會應用可選的'where'子句:我需要某種'外部連接'來工作,因此如果EntityA具有0/null標籤,它仍將返回結果集中。出於這個原因,我會考慮索引屬性的方法,以防萬一跳過的結果問題可能會干擾。謝謝! – Nick

+0

你是說你想回到每個'EntityA'?或者你想要包含沒有標籤的EntityA? –

+0

我想包含沒有標籤的'EntityA's。 – Nick