2012-05-15 2 views
4

웹 사이트의 페이지 방문을 추적하는 응용 프로그램이 있습니다. 방문자가 웹 사이트로 이동하는 경우Raven DB :이 다중 맵/축소 인덱스의 문제점은 무엇입니까?

public class VisitSession { 
    public string SessionId { get; set; } 
    public DateTime StartTime { get; set; } 
    public string UniqueVisitorId { get; set; } 
    public IList<PageVisit> PageVisits { get; set; } 
} 

이 방문 세션을 시작합니다 여기 내 모델입니다. 하나의 방문 세션에는 많은 페이지 방문이 있습니다. 추적기는 방문자가 웹 사이트에 처음 방문 할 때 UniqueVisitorId (GUID) 쿠키를 작성합니다. 그래서 우리는 방문객이 방문객을 돌려주고 있는지 알 수 있습니다.

이제 각 날에 대해 TotalVisitSessions, TotalPageVisits, TotalUniqueVisitors를 표시하는보기를 작성하고 싶습니다.

public class VisitSummaryByDateIndex : AbstractMultiMapIndexCreationTask<VisitSummaryByDate> 
{ 
    public VisitSummaryByDateIndex() 
    { 
     AddMap<VisitSession>(sessions => from s in sessions 
              select new VisitSummaryByDate 
              { 
               Date = s.StartTime.Date, 
               TotalVisitSessions = 1, 
               TotalPageVisits = 0, 
               TotalNewVisitors = s.IsNewVisit ? 1 : 0, 
               TotalUniqueVisitors = 0, 
               UniqueVisitorId = s.UniqueVisitorId 
              }); 

     AddMap<PageVisit>(visits => from v in visits 
            select new VisitSummaryByDate 
            { 
             Date = v.VisitTime.Date, 
             TotalVisitSessions = 0, 
             TotalPageVisits = 1, 
             TotalNewVisitors = 0, 
             TotalUniqueVisitors = 0, 
             UniqueVisitorId = String.Empty 
            }); 

     Reduce = results => from result in results 
          group result by result.Date into g 
          select new VisitSummaryByDate 
          { 
           Date = g.Key, 
           TotalVisitSessions = g.Sum(it => it.TotalVisitSessions), 
           TotalPageVisits = g.Sum(it => it.TotalPageVisits), 
           TotalNewVisitors = g.Sum(it => it.TotalNewVisitors), 
           TotalUniqueVisitors = g.Select(it => it.UniqueVisitorId).Where(it => it.Length > 0).Distinct().Count(), 
           UniqueVisitorId = String.Empty 
          }; 
    } 
} 

문제는 때때로 인덱스 결과의 TotalUniqueVisitors 때때로, 1 인 2입니다하지만 데이터를 확인에서 "TotalUniqueVisitors"계산에, 그것은 결코 것 : 그래서 나는이 멀티 맵이 감소 쓰기 너무 적게. 내 Map/Reduce 구문에 문제가 있습니까?

관련 게시물 : 샘플 데이터Raven DB: How to create "UniqueVisitorCount by date" index

코드는 여기에서 찾을 수 있습니다 :https://gist.github.com/2702071

답변

2

실제로 Reduce는 결과에 대해 여러 번 처리됩니다. 인덱스는 한 번만 발생하며 전체 결과 집합에 액세스 할 수 있다고 가정합니다. 이 같은 모습에

검지 필요 :

public class VisitSummaryByDateIndex : AbstractMultiMapIndexCreationTask<VisitSummaryByDate> 
{ 
    public VisitSummaryByDateIndex() 
    { 
     AddMap<VisitSession>(sessions => from s in sessions 
             select new VisitSummaryByDate 
             { 
              Date = s.StartTime.Date, 
              TotalVisitSessions = 1, 
              TotalPageVisits = 0, 
              TotalNewVisitors = s.IsNewVisit ? 1 : 0, 
              TotalUniqueVisitors = 1, 
              UniqueVisitorId = new[]{s.UniqueVisitorId} 
             }); 

     AddMap<PageVisit>(visits => from v in visits 
            select new VisitSummaryByDate 
            { 
             Date = v.VisitTime.Date, 
             TotalVisitSessions = 0, 
             TotalPageVisits = 1, 
             TotalNewVisitors = 0, 
             TotalUniqueVisitors = 0, 
             UniqueVisitorId = new string[0] 
            }); 

     Reduce = results => from result in results 
          group result by result.Date into g 
          select new VisitSummaryByDate 
          { 
           Date = g.Key, 
           TotalVisitSessions = g.Sum(it => it.TotalVisitSessions), 
           TotalPageVisits = g.Sum(it => it.TotalPageVisits), 
           TotalNewVisitors = g.Sum(it => it.TotalNewVisitors), 
           TotalUniqueVisitors = g.Sum(it => it.TotalUniqueVisitors),, 
           UniqueVisitorId = g.Select(x=>x.UniqueVisitorId).Distinct() 
          }; 
    } 
} 
+1

(나는 당신에게 질문하고 있다고 믿을 수 없다!) 그러나 이것은 효과가 없다. 각 세션이 새로운 고유 ID 일 필요는 없으므로 합계가 올바르지 않습니다. 또한, 나는 UniqueVisitorId가'IEnumerable '이 될 것으로 가정하고 컴파일하지 않습니다. 그러나,이 질문에 게시물을보고 (http://stackoverflow.com/questions/10597359/raven-db-how-to-create-uniquevisitorcount-by-date-index) 그 필드는 생각하지 않아요. 중요한 어쨌든, 따라서 내 대답은 그냥 FirstOrDefault로 설정. – Simon

+1

실제로 여기에서'TotalUniqueVisitors'를 제거하고'UniqueVisitorId.Count'를 사용하여 실제 순 방문자 수를 얻어야합니다. – configurator

+0

@ 사이먼 당신과 동의하십시오. 하지만 FirstOrDefault로 설정하는 것이 올바르지 않다고 생각합니다. reduce 함수는 두 번 이상 프로세스가 될 것이기 때문에 (입력 자체를 출력으로 취할 수 있습니다). 따라서 FirstOrDefault를 사용하면 1 TotalUniqueVisits의 결과를 얻을 수 있습니다. Ayende의 대답에 따라 최종 해결책을 찾은 것 같습니다. 하지만 지금은 성과에 대해 생각하고 있습니다. reduce 함수의 SelectMany는 결과 문서를 매우 크게 만듭니다. 너희들은 그것에 대해 어떻게 생각하니? 새로운 요지가 있습니다 : https://gist.github.com/2702071 –

2

올바른 인덱스는 다음과 같습니다

public class VisitSummaryByDateIndex : AbstractMultiMapIndexCreationTask<VisitSummaryByDate> 
{ 
    public VisitSummaryByDateIndex() 
    { 
     AddMap<VisitSession>(sessions => from s in sessions 
             select new VisitSummaryByDate 
             { 
              Date = s.StartTime.Date, 
              TotalVisitSessions = 1, 
              TotalPageVisits = 0, 
              TotalNewVisitors = s.IsNewVisit ? 1 : 0, 
              TotalUniqueVisitors = 0, 
              UniqueVisitorId = s.UniqueVisitorId 
             }); 

     AddMap<PageVisit>(visits => from v in visits 
            select new VisitSummaryByDate 
            { 
             Date = v.VisitTime.Date, 
             TotalVisitSessions = 0, 
             TotalPageVisits = 1, 
             TotalNewVisitors = 0, 
             TotalUniqueVisitors = 0, 
             UniqueVisitorId = string.Empty, 
            }); 

     Reduce = results => from result in results 
          group result by result.Date into g 
          select new VisitSummaryByDate 
          { 
           Date = g.Key, 
           TotalVisitSessions = g.Sum(it => it.TotalVisitSessions), 
           TotalPageVisits = g.Sum(it => it.TotalPageVisits), 
           TotalNewVisitors = g.Sum(it => it.TotalNewVisitors), 
           TotalUniqueVisitors = g.Select(it => it.UniqueVisitorId).Where(x => x.Length > 0).Distinct().Count(), 
           UniqueVisitorId = g.FirstOrDefault().UniqueVisitorId, 
          }; 
    } 
} 

차이가 UniqueVisitorId이 설정되어 있다는 것입니다 감소. 나는 이것이 왜 필요한지 100 % 확실하지 않다. 나는 인정해야한다.

+0

아, 그것은이 필요 왜 우리가 지금 알고 Ayende의 대답에 감사합니다. Ayende와 같은 배열을 사용하면 어떤 이점이 있는지 잘 모르겠지만 내 대답에 따라 문자열을 사용하여 작동합니다. – Simon