1

タイトルよりもコードから何をしたいのかがより明確になることを願っています。基本的に、私は 2 つのフィールドでグループ化しており、結果を Map フェーズで構築されたすべての ProductKey のコレクションに減らしたいと考えています。

public class BlockResult
{
    public Client.Names ClientName;
    public string Block;
    public IEnumerable<ProductKey> ProductKeys;
}

public Block()
{
    Map = products =>
            from product in products
            where product.Details.Block != null
            select new
            {
                product.ClientName,
                product.Details.Block,
                ProductKeys = new List<ProductKey>(new ProductKey[]{
                    new ProductKey{
                        Id = product.Id,
                        Url = product.Url
                    }
                })
            };

    Reduce = results =>
            from result in results
            group result by new {result.ClientName, result.Block} into g
            select new BlockResult
            {
                ClientName = g.Key.ClientName,
                Block =  g.Key.Block,
                ProductKeys = g.SelectMany(x=> x.ProductKeys)
            };
}

奇妙な System.InvalidOperationException と、基本的にリストを int (?) で初期化しようとしているソース コード ダンプが表示されます。

ProductKey を IEnumerable ProductIds だけに置き換えようとすると (コードに適切な変更を加えます)。その後、コードは実行されますが、reduce で結果が得られません。

4

2 に答える 2

3

あなたはおそらくこれをしたくないでしょう。本当にこの方法でクエリを実行する必要がありますか? コンテキストがわかっている場合は、おそらくこれを行う必要があります。

var q = session.Query<Product>()
               .Where(x => x.ClientName == "Joe" && x.Details.Block == "A");

ただし、元の質問に答えるには、次のインデックスが機能します。

public class Products_GroupedByClientNameAndBlock : AbstractIndexCreationTask<Product, Products_GroupedByClientNameAndBlock.Result>
{
    public class Result
    {
        public string ClientName { get; set; }
        public string Block { get; set; }
        public IList<ProductKey> ProductKeys { get; set; }
    }

    public class ProductKey
    {
        public string Id { get; set; }
        public string Url { get; set; }
    }

    public Products_GroupedByClientNameAndBlock()
    {
        Map = products =>
                from product in products
                where product.Details.Block != null
                select new {
                                product.ClientName,
                                product.Details.Block,
                                ProductKeys = new[] { new { product.Id, product.Url } }
                            };

        Reduce = results =>
                    from result in results
                    group result by new { result.ClientName, result.Block }
                    into g
                    select new {
                                g.Key.ClientName,
                                g.Key.Block,
                                ProductKeys = g.SelectMany(x => x.ProductKeys)
                            };
    }
}
于 2012-12-20T14:11:10.557 に答える
0

複製すると、同じ InvalidOperationException が発生し、インデックスの定義を理解していないことが示されます (簡潔にするためにスタック トレースは省略されています)。

Url: "/indexes/Keys/ByNameAndBlock" System.InvalidOperationException: クエリを理解できませんでした:

ここで何をしようとしているのかまだ完全にはわからないので、これはあなたが求めているものではないかもしれませんが、次の作業を行うことができました. 要するに、Map/Reduce は無名オブジェクトを扱うため、カスタム型に強く入力しても Raven には意味がありません。

public class Keys_ByNameAndBlock : AbstractIndexCreationTask<Product, BlockResult>
{
    public Keys_ByNameAndBlock()
    {
        Map = products =>
              from product in products
              where product.Block != null
              select new
                  {
                      product.Name,
                      product.Block,
                      ProductIds = product.ProductKeys.Select(x => x.Id)
                  };

        Reduce = results =>
                 from result in results
                 group result by new {result.Name, result.Block}
                 into g
                 select new
                     {
                         g.Key.Name,
                         g.Key.Block,
                         ProductIds = g.SelectMany(x => x.ProductIds)
                     };
    }

}

public class Product
{
    public Product()
    {
        ProductKeys = new List<ProductKey>();
    }

    public int ProductId { get; set; }
    public string Url { get; set; }
    public string Name { get; set; }
    public string Block { get; set; }
    public IEnumerable<ProductKey> ProductKeys { get; set; }
}

public class ProductKey
{
    public int Id { get; set; }
    public string Url { get; set; }
}

public class BlockResult
{
    public string Name { get; set; }
    public string Block { get; set; }
    public int[] ProductIds { get; set; }
}
于 2012-12-20T13:01:07.777 に答える