2012-07-07 5 views
1

이 긴 쿼리를 사용하여 죄송합니다. 전체 테스트를 추가하여 새내기가이 두뇌를 완전히 녹이기가 더 쉬워졌습니다.RavenDB MultiMapReduce 올바른 값을 반환하지 않는 합

사용 지침은 다음과 같습니다

using System.Collections.Generic; 
using System.Linq; 
using NUnit.Framework; 
using Raven.Client; 
using Raven.Client.Embedded; 
using Raven.Client.Indexes; 

내가 너무 긴 해요 경우 의견을 남길 수 있지만 완전한 테스트를 추가하면 가능성이 무엇이 잘못 갈 수하세요? 여기

[TestFixture] 
public class ClicksByScoreAndCardTest 
{ 
    private IDocumentStore _documentStore; 

    [SetUp] 
    public void SetUp() 
    { 
     _documentStore = new EmbeddableDocumentStore {RunInMemory = true}.Initialize(); 
     _documentStore.DatabaseCommands.DisableAllCaching(); 

     IndexCreation.CreateIndexes(typeof (ClicksBySearchAndProductCode).Assembly, _documentStore); 
    } 

    [TearDown] 
    public void TearDown() 
    { 
     _documentStore.Dispose(); 
    } 

    [Test] 
    public void ShouldCountTotalLeadsMatchingPreference() 
    { 
     var userFirst = new User {Id = "users/134"}; 
     var userSecond = new User {Id = "users/135"}; 
     var searchFirst = new Search(userFirst) 
           { 
            Id = "searches/24", 
            VisitId = "visits/63" 
           }; 
     searchFirst.Result = new Result(); 
     searchFirst.Result.Rows = new List<Row>(
      new[] 
       { 
        new Row {ProductCode = "CreditCards/123", Score = 6}, 
        new Row {ProductCode = "CreditCards/124", Score = 4} 
       }); 

     var searchSecond = new Search(userSecond) 
           { 
            Id = "searches/25", 
            VisitId = "visits/64" 
           }; 

     searchSecond.Result = new Result(); 
     searchSecond.Result.Rows = new List<Row>(
      new[] 
       { 
        new Row {ProductCode = "CreditCards/122", Score = 9}, 
        new Row {ProductCode = "CreditCards/124", Score = 4} 
       }); 

     var searches = new List<Search> 
          { 
           searchFirst, 
           searchSecond 
          }; 

     var click = new Click 
         { 
          VisitId = "visits/64", 
          ProductCode = "CreditCards/122", 
          SearchId = "searches/25" 
         }; 

     using (var session = _documentStore.OpenSession()) 
     { 
      foreach (var search in searches) 
      { 
       session.Store(search); 
      } 
      session.Store(click); 
      session.SaveChanges(); 
     } 

     IList<ClicksBySearchAndProductCode.MapReduceResult> clicksBySearchAndProductCode = null; 
     using (var session = _documentStore.OpenSession()) 
     { 
      clicksBySearchAndProductCode = session.Query<ClicksBySearchAndProductCode.MapReduceResult>(ClicksBySearchAndProductCode.INDEX_NAME) 
       .Customize(x => x.WaitForNonStaleResults()).ToArray(); 
     } 
     Assert.That(clicksBySearchAndProductCode.Count, Is.EqualTo(4)); 
     var mapReduce = clicksBySearchAndProductCode 
      .First(x => x.SearchId.Equals("searches/25") 
         && x.ProductCode.Equals("CreditCards/122")); 
     Assert.That(mapReduce.Clicks, 
       Is.EqualTo(1)); 
    } 
} 

public class ClicksBySearchAndProductCode : 
    AbstractMultiMapIndexCreationTask 
     <ClicksBySearchAndProductCode.MapReduceResult> 
{ 
    public const string INDEX_NAME = "ClicksBySearchAndProductCode"; 

    public override string IndexName 
    { 
     get { return INDEX_NAME; } 
    } 

    public class MapReduceResult 
    { 
     public string SearchId { get; set; } 
     public string ProductCode { get; set; } 
     public string Score { get; set; } 
     public int Clicks { get; set; } 
    } 

    public ClicksBySearchAndProductCode() 
    { 
     AddMap<Search>(
      searches => 
      from search in searches 
      from row in search.Result.Rows 
      select new 
      { 
       SearchId = search.Id, 
       ProductCode = row.ProductCode, 
       Score = row.Score.ToString(), 
       Clicks = 0 
      }); 
     AddMap<Click>(
      clicks => 
      from click in clicks 
      select new 
      { 
       SearchId = click.SearchId, 
       ProductCode = click.ProductCode, 
       Score = (string)null, 
       Clicks = 1 
      }); 
     Reduce = 
      results => 
      from result in results 
      group result by 
       new { SearchId = result.SearchId, ProductCode = result.ProductCode } 
       into g 
       select 
        new 
        { 
         SearchId = g.Key.SearchId, 
         ProductCode = g.Key.ProductCode, 
         Score = g.First(x => x.Score != null).Score, 
         Clicks = g.Sum(x => x.Clicks) 
        }; 
    } 
} 
public class User 
{ 
    public string Id { get; set; } 
} 

public class Search 
{ 
    public string Id { get; set; } 
    public string VisitId { get; set; } 
    public User User { get; set; } 

    private Result _result = new Result(); 

    public Result Result 
    { 
     get { return _result; } 
     set { _result = value; } 
    } 

    public Search(User user) 
    { 
     User = user; 
    } 
} 

public class Result 
{ 
    private IList<Row> _rows = new List<Row>(); 

    public IList<Row> Rows 
    { 
     get { return _rows; } 
     set { _rows = value; } 
    } 
} 

public class Row 
{ 
    public string ProductCode { get; set; } 
    public int Score { get; set; } 
} 

public class Click 
{ 
    public string VisitId { get; set; } 
    public string SearchId { get; set; } 
    public string ProductCode { get; set; } 
} 

내 문제는 내가 그 특정 테스트 한 것으로 카운트 기대이지만, 그냥 클릭지도에서 클릭 수를 추가하지 않는 것, 그 결과는 0 클릭합니다. 나는 완전히 혼란스럽고, 내 문제에 대한 정말로 간단한 해결책이 있다고 확신하지만, 나는 그것을 찾을 수 없다. ..

.. 거기에 주말 전사가있다. 나를 그의 날개 밑으로 데려가 라.

+0

죄송합니다, 나는 f를 버그/***까지 .. 정신 노트, 사용 발견 사용하지 않음 : 점수 = g.First (x => x.Score! = null). 점수 – Molibar

답변

1

예, 그것은 사소한 것이지만 여전히 뇌 용해 상태였습니다. 감소 적절한은 다음과 같아야합니다

Reduce = 
    results => 
    from result in results 
    group result by 
     new { SearchId = result.SearchId, ProductCode = result.ProductCode } 
     into g 
     select 
      new 
      { 
       SearchId = g.Key.SearchId, 
       ProductCode = g.Key.ProductCode, 
       Score = g.Select(x=>x.Score).FirstOrDefault(), 
       Clicks = g.Sum(x => x.Clicks) 
      }; 

모든지도 null이 아닌 값으로 설정 점수를했다, 따라서 내 원래 버전에 문제가 있었다 :

Score = g.First(x => x.Score != null).Score 

을 정신 노트, 사용 :

Score = g.Select(x=>x.Score).FirstOrDefault() 

는 사용하지 마십시오

점수 = g.Select (X => x.Score) .FirstOrDefault() 돈 : 당신을 귀찮게
Score = g.First(x => x.Score != null).Score 
관련 문제