2012-12-05 2 views
1

나는 다음과 같은 모델이 있습니다방법 및 조건 RavenDB 쿼리에 LINQ의 WHERE 절에

public class Clip { 
    public Guid ClipId { get; set; } 
    public IList<StateChange> StateChanges { get; set; } 
} 

public class StateChange { 
    public string OldState { get; set; } 
    public string NewState { get; set; } 
    public DateTime ChangedAt { get; set; } 
} 

을 그리고 이것은 쿼리 까마귀 방법입니다

var now = DateTime.UtcNow; 
var since = now.AddSeconds(60); 
string state = "some state of interest"; 
using (var session = docStore.OpenSession()) { 
      RavenQueryStatistics stats; 
      session.Query<Clip>() 
       .Statistics(out stats) 
       .Where(
        p => p.StateChanges.Any(a => (since > a.ChangedAt && a.NewState == state)) 
        && !p.StateChanges.Any(a => (a.OldState == state && now > a.ChangedAt))) 
       .ToArray(); 
      return stats.TotalResults; 
     } 

내가 얻을 싶어 (StateChange.CreatedAt, sinceNewState"some state of interest" 일 때) (nowOldState"some state of interest" 일 때)이 아닌 모든 Clip 레코드를 계산하십시오.).

위에서 사용 된 술어가 object에 대해 linq에서 작동하지만, linq에서 까마귀에게 작동하지 않는 것 같습니다 (예 : 예상 결과를 리턴하지 않음). 왼쪽에있는 표현식이 true로 평가되면 표현식 && !.p.StateChanges.Any....이 평가되지 않기 때문입니다. 이 문제를 해결할 방법이 있습니까?

+0

"작동하지 않음"이란 무엇을 의미합니까? 오류가 있습니까? –

+0

아니요, 예상 결과를 반환하지 않음을 의미합니다. 즉, 오른쪽 표현식을 무시합니다. –

+0

어떻게 무시할 것입니까? 첫 번째 조건이 참이면 전체 조건 결과를 얻기 위해 올바른 조건을 평가해야합니다. –

답변

3

조건 평가와 관련이 없습니다. & &은 정상적으로 작동합니다.

문제는 RavenDB가 .All (...) 또는! .Any (...)를 사용하는 쿼리를 제대로 처리하지 않는다는 것입니다. 이것은 까마귀의 동적 색인 엔진이 linq 문을 평가하는 방식 때문입니다. 각 상태 변경 항목과 같은 여러 항목을 고려해야하는 작업에는 작동하지 않는 각 StateChange 항목에 대해 별도의 색인 항목을 작성하려고합니다.

here에 이미 기록 된 문제가 있습니다. 이 방법으로 쿼리하려고 할 때 의미있는 예외를 던지기 위해 빌드 2151에서 닫혔습니다. 미래의 어떤 시점에 실제로 이러한 유형의 쿼리를 실제로 올바르게 평가할 수있는 방법이 있는지 재평가 할 수 있습니다.

업데이트

나는 당신의 도전에 대해 생각해 봤는데, 그리고 another related one, 그리고 당신이 할 수있는 새로운 기술을 마련 할 수 있었다. 만약 당신이 원하는 물론

public class Clips_ByStateChange : AbstractIndexCreationTask<Clip> 
{ 
    public Clips_ByStateChange() 
    { 
    Map = clips => 
      from clip in clips 
      select new { 
       OldState = clip.StateChanges 
        .Select(x => x.OldState + "|" + x.ChangedAt.ToString("o")), 
       NewState = clip.StateChanges 
        .Select(x => x.NewState + "|" + x.ChangedAt.ToString("o")) 
      }; 
    } 
} 

var results = session.Advanced.LuceneQuery<Clip, Clips_ByStateChange>() 
    .Where(string.Format(
     "NewState: {{{0}|* TO {0}|{1}}} AND -OldState: {{{0}|* TO {0}|{2}}}", 
     state, since.ToString("o"), now.ToString("o"))); 

, 당신은 여전히 ​​그냥 통계를 수행 할 수 있습니다 그것은 정적 인덱스와 루씬 쿼리가 필요합니다.