2013-01-14 3 views
2

I 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에 존재할 수를 그 때문에 교차 할 수 있습니다.

내가 검색 할 수있는 방법 EntityB에 태그를 교차 한 것은 EntityBName 속성이 특정 값과 같은 곳마다 EntityA?

+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'를 포함하고 싶습니다. – Nick