2015-02-12 103 views
2

我想要做的是從大約400萬行的表中獲取行,以便將其與ElasticSearch建立索引。從EF6數據庫中選擇大量數據異步

基礎索引器將使用IndexManyAsync並批量賦予給它的枚舉。

喜歡的東西:

public void IndexMany(IEnumerable<IIndexModel> indexModels) { 
    var client = new ElasticClient(settings); 
    var batches = indexModels.Batch(1000); 
    var tasks = new List<Task>(); 
    Parallels.ForEach(partitions, partition => 
    { 
     var task = client.IndexManyAsync(partition); 
     tasks.Add(task); 
    } 

    Task.WaitAll(tasks.ToArray()); 
} 

這麼一點,我想創建一個枚舉與IndexModels。

IndexModels將採用實體並通過給定的實體初始化各種屬性。例如:

public class FooModel<T> : IIndexModel 
{ 
    public FooModel(T entity) 
    { 
     Name = entity.Name; 
    } 

    public string Name { get; set; } 
} 

我有一個包含~4mil行的表,這顯然需要一些時間來查詢。所以我想要做的就是做這個異步。

我已經嘗試過這樣做的各種方法。第一種方法是對查詢進行批量處理,並對其進行相似處理。這給了ObjectContext各種併發問題。

public void IndexAllModels() { 
    using (var db = new Db()) { 
     var batchedEntities = db.BigTable.Select(p => p).Batch(1000); 

     Parallels.ForEach(batchedEntities, currentBatch => 
     { 
      var indexModels = new List<IIndexModel>(); 
      foreach (var entity in currentBatch) 
      { 
       var indexModel = new FooModel<BigTable>(entity); 
       indexModels.Add(indexModel); 
      } 

      IndexMany(indexModels); 
     } 
    } 
} 

我在想,如果有什麼辦法通過使用新的EF6異步操作來做到這一點?

+0

'indexModels'的大小是多少? – i3arnon 2015-02-12 09:45:41

+0

可能會有所不同。一些indexmodels設置約20個屬性,一些只有5個左右。 – Ekenstein 2015-02-12 11:13:39

+0

我的意思是有多少... – i3arnon 2015-02-12 11:15:44

回答

2

自然使用async API的優點是您不需要使用線程來使用它們。自從一路下降到WinAPI級別,There Is No Thread

您可以創建需要一個IEnumerable<IndexModel>和使用的ElasticSearchs異步API,像這樣的方法:

public async Task IndexManyAsync(IEnumerable<IIndexModel> indexModels) 
{ 
    var client = new ElasticClient(settings); 

    var taskBatches = indexModels.Batch(1000) 
           .Select(partition => 
             client.IndexManyAsync(partition)); 

    await Task.WhenAll(taskBatches); 
} 

假設IndexManyAsync使用爲每個請求單獨DbContext,這應該工作。

+0

傳遞數據的中介來增加大量開銷謝謝!這解釋了一些。但是,這並沒有回答如何從數據庫異步檢索大塊數據的問題。 我可能不太清楚我的問題。 但選擇4磨坊行也可能是一個內存問題。 – Ekenstein 2015-02-12 09:56:05

+0

@Ekenstein噢,我以爲你已經在使用'Batch'處理每個1000個請求。 – 2015-02-12 09:57:30

+0

是的。我使用morelinq來批量查詢。但是,當試圖使用並行foreach獲取每批時,由於objectcontext似乎不是線程安全的,因此會變得很麻煩。 另外,我還希望實例化每個實體並行的索引模型。 – Ekenstein 2015-02-12 11:15:05