1

我希望从代码中我想做什么比标题更清楚。基本上我按 2 个字段分组,并希望将结果减少到一个集合中,所有 ProductKey 在 Map 阶段构建。

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 (?) 初始化列表。

如果我尝试仅用 IEnumerable ProductIds 替换 ProductKey(并在代码中进行适当的更改)。然后代码运行,但我没有得到任何减少的结果。

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,指出它不理解索引定义(为简洁起见,省略了堆栈跟踪)。

网址:“/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 回答