如何在RavenDb中查询展平子集合?需要索引?

its*_*urs 3 c# linq ravendb

我在C#web项目中使用RavenDb.我有一个对象,我需要查询其子集合,每个子对象1行和一些根/父对象属性.
注意:这不是实际设计,只是简化了这个问题.

    public class OrderLine
    {
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public DateTime? ShipDate { get; set; }
    }
    public class Order
    {
        public int OrderId { get; set; }
        public string CustomerName { get; set; }
        public DateTime OrderDate { get; set; }
        public List<OrderLine> OrderLines { get; set; }

    }
Run Code Online (Sandbox Code Playgroud)

订单行的订单是一个单独的文档.ShipDate将在每一行更新,因为并非所有产品都有库存.

我需要能够创建使用以下列发送的最近10个产品的列表:

OrderId
Customer
ProductName
ShipDate
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为不支持SelectMany:

        var query = from helper in RavenSession.Query<Order>()
                        .SelectMany(l => l.OrderLines, (order, orderline) => 
                            new { order, orderline })
                    select new 
                    {
                        helper.order.OrderId,
                        helper.order.CustomerName,
                        helper.orderline.ProductName,
                        helper.orderline.ShipDate

                    };
        var result = query.Where(x => x.ShipDate.HasValue)
            .OrderByDescending(x => x.ShipDate.Value).Take(10);
Run Code Online (Sandbox Code Playgroud)

我认为正确的做法是创建一个索引,这将使列表变得扁平,但我没有取得任何成功.我不相信Map-Reduce情况会起作用,因为据我了解它会有效地执行一个组,通过该组将文档数减少到较少的行(在索引中).但在这种情况下,我试图将文档数量扩展到更多行(在索引中).

我宁愿不把每个OrderLine放在一个单独的文件中,但我不知道我的选择是什么.

Mat*_*int 5

由于您希望按子类中的字段进行筛选和排序,因此您需要确保索引和存储所需的所有字段.

public class ShippedItemsIndex
    : AbstractIndexCreationTask<Order, ShippedItemsIndex.Result>
{
    public class Result
    {
        public int OrderId { get; set; }
        public string CustomerName { get; set; }
        public string ProductName { get; set; }
        public int Quantity { get; set; }
        public DateTime ShipDate { get; set; }
    }

    public ShippedItemsIndex()
    {
        Map = orders => 
            from order in orders
            from line in order.OrderLines
            where line.ShipDate != null
            select new
            {
                order.OrderId,
                order.CustomerName,
                line.ProductName,
                line.Quantity,
                line.ShipDate
            };

        StoreAllFields(FieldStorage.Yes);
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以从索引投影到结果中.

var query = session.Query<Order, ShippedItemsIndex>()
    .ProjectFromIndexFieldsInto<ShippedItemsIndex.Result>()
    .OrderByDescending(x => x.ShipDate)
    .Take(10);

var results = query.ToList();
Run Code Online (Sandbox Code Playgroud)

这是一个完整的测试证明.