1

この長い質問で申し訳ありませんが、私はテスト全体を追加することにしました。これは、初心者でもこの完全な頭脳の溶解を手伝ってくれるようにするためです。

usingディレクティブは次のとおりです。

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; }
}

ここでの私の問題は、その特定のテストでカウントが1であると期待していることですが、クリックマップにクリックが追加されていないようで、結果は0クリックです。私は完全に混乱していて、私の問題には本当に簡単な解決策があると確信していますが、それを見つけることができません。

..私を彼の翼の下に連れて行くことができる週末の戦士がそこにいることを願っています。

4

1 に答える 1

1

はい、それは私にとっては些細なことではありませんが、それでも脳の溶解でした。適切なreduceは次のようになります。

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()

使用しないでください:

Score = g.First(x => x.Score != null).Score
于 2012-07-07T21:01:05.233 に答える