使用NEST进行弹性搜索 - 异步操作

时间:2014-03-20 14:16:31

标签: c# elasticsearch nest

寻找使用Nest Async函数的示例 -

我想索引大量的记录,可能是100000.所以,我会使用IndexManyAsync,但我对Async不太了解。 IndexManyAsync返回任务。所以我正在寻找一个如何实现它的例子。

我要做的非异步方式是:记录50条记录,索引,接下来的50条记录,索引等......

使用Async,我应该使用所有记录调用一次IndexManyAsync吗?或者仍然一次做50?我是否调用该方法,重新获取任务,然后调用Task.Start?我是否制作了一系列任务然后一次运行?等...

寻找一些指导......

2 个答案:

答案 0 :(得分:2)

有一个在源存储库中的NEST Profiling.Indexing.Tester.cs类中使用IndexManyAsync的示例。这应该让你开始朝着正确的方向前进。

答案 1 :(得分:1)

所以,我基于该测试创建了一个方法:

public IEnumerable<IBulkResponse> ExportAllProducts(string indexName, int? productsCount)
    {
        var allTasks = ExportBulkProducts(indexName,productsCount);

        var results = new List<IBulkResponse>();
        try
        {
            var tokenSource2 = new CancellationTokenSource();
            var cancellationToken = tokenSource2.Token;
            Task.WaitAll(allTasks.ToArray<Task>(), cancellationToken);

            results = allTasks.Select(response => response.Result).ToList();
        }
        catch (AggregateException e)
        {
            var messages = new List<String>();
            messages.AddRange(e.InnerExceptions.Select(v => e.Message + " " + v.Message));
            throw new CustomException(messages);
        }
        return results;
    }

    /// <summary>
    /// Genete the tasks needed to run
    /// </summary>
    /// <param name="indexName">The index name</param>
    /// <param name="productsCount">The number of products to index</param>
    /// <returns>List of Tasks</returns>
    private IList<Task<IBulkResponse>> ExportBulkProducts(string indexName, int? productsCount)
    {
        var allTasks = new List<Task<IBulkResponse>>();
        using (var productRepository = new ProductRepository(new SearchContext()))
        {
            var totalProducts = productsCount ?? productRepository.TotalProducts();

            var itemsPerPage = 50;
            if (productsCount != null)
            {
                var count = productsCount.Value;
                itemsPerPage = count < 50 ? productsCount.Value : 50;
            }
            int totalPages = totalProducts / itemsPerPage;

            for (var i = 0; i < totalPages; i++)
            {
                var products = productRepository.SelectAllProducts(itemsPerPage, itemsPerPage * i);
                var response = Client.IndexAsync(indexName, typeof(ElasticSearchProduct), products, true);
                allTasks.Add(response);
            }
        }
        return allTasks;
    }

这在技术上有效,这意味着我得到了可测试的结果。但我不确定它实际上是在发生异步。具体来说,当我单步执行代码时,每次调用IndexAsync时,我都会返回一个Task并将其添加到一个任务数组中,以便一起运行,但是这个任务的字段告诉我它已经运行了,所以当我立刻打电话给所有的任务时:

Task.WaitAll(allTasks.ToArray<Task>(), cancellationToken);

它完全没有时间,因为所有任务都已经运行。也许这是正确的?我以为它会等待并一起完成所有任务?