2014-01-13 77 views
3

我在C#web項目中使用RavenDb。我有一個對象,我需要查詢它的子集合,每個子對象有一行,還有一些根/父對象屬性。
注意:這不是實際的設計,只是簡化了這個問題。如何查詢RavenDb中的扁平子集合?需要索引?

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

    } 

帶有命令行的訂單是單個文檔。 ShipDate將在每條生產線上進行更新,因爲並非所有產品都有庫存。

我需要能夠創建具有以下的列發送的最後10個產品列表:

OrderId 
Customer 
ProductName 
ShipDate 

這行不通,因爲不支持的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); 

我相信正確的做法是創建一個索引,將列表放平,但我沒有取得任何成功。我不相信Map-Reduce的情況會起作用,因爲據我所知,它將有效地完成一個組,將文檔的數量減少到較少的行數(在索引中)。但在這種情況下,我試圖將文檔數量擴展到更多行(在索引中)。

我寧願不把每個OrderLine放在單獨的文檔中,但我不知道我的選擇是什麼。

回答

4

由於您想按照子類中的字段進行過濾和排序,因此您需要確保所需的所有字段都已編入索引,並且存儲爲

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

然後你可以project from the index到你的結果。

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

var results = query.ToList(); 

Here is a complete test demonstrating.

+0

真棒...幫助我極大。從SQL過渡不容易:) – itsallyours

相關問題