c# - Entity Framework 将数千个对象传输到 Elastic Search

标签 c# entity-framework nest

我正在创建一个网络应用程序,它将拥有一个关于世界上每个城镇、地区和国家的数据库,以允许将其他对象映射到一个位置。作为应用程序的一部分,我希望用户能够搜索某个地方,为此我使用 Elastic Search 为所有内容编制索引。为了与 Elastic Search 交互,我使用了 NEST。

我有以下代码:

public void RefreshLocationIndex()
{
    int count;
    using (var dbContext = new ModelContext())
    {
        IndexMany(dbContext.Countries, "Country");
    }

    using (var dbContext = new ModelContext())
    {
        count = dbContext.Regions.AsNoTracking().Count();
    }
    for (var i = 0; i <= count; i += BATCH_SIZE)
    {
        using (var innerContext = new ModelContext())
        {
            IndexMany(innerContext.Regions.OrderBy(t => t.RegionID).Skip(i).Take(BATCH_SIZE),
                    "Region");
        }
    }


    using (var dbContext = new ModelContext())
    {
        count = dbContext.Towns.AsNoTracking().Count();
    }
    for (var i = 0; i <= count; i += BATCH_SIZE)
    {
        using (var innerContext = new ModelContext())
        {
            IndexMany(innerContext.Towns.AsNoTracking().OrderBy(t => t.TownID).Skip(i).Take(BATCH_SIZE), "Town");
        }
    }
}

public void IndexMany(IQueryable<Entity> objects, string type)
{
    var itemCount = objects.Count();
    if (itemCount > 0)
    {
        SearchClient.Instance.IndexManyAsync(objects, SearchClient.Instance.Settings.DefaultIndex, type);
    }
}

如您所见,我将非常大的表分成批处理,以避免将太多数据加载到内存中。问题是这不起作用,而且我不断出现内存不足异常。我认为为每个批处理使用一个新的上下文可以避免这个问题,因为当处理上下文时它会处理它加载的所有实体,但事实并非如此。有什么想法吗?

正如数据量的指示: 国家表有193条记录 地区表有 80,523 条记录 town表有2,743,469条记录

最佳答案

我不知道 ElasticSearch 和 NEST,但根据 their source code , IndexManyAsync 每次调用时都会创建一个新任务。

因此,如果任务的执行速度比 Entity Framework 实体化实体的速度慢得多,您将拥有大量正在执行(或等待执行)的任务,每个任务都加载了 BATCH_SIZE 个实体内存,因为这些实体作为参数传递:所以基本上所有实体都将同时加载到内存中。

我不确定如何解决这个问题,因为我不知道 NEST 或 ElasticSearch 关于批量索引的最佳实践,但这里是对你的问题的解释。

关于c# - Entity Framework 将数千个对象传输到 Elastic Search,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19605834/

相关文章:

c# - 如何 Moq Entity Framework SqlQuery 调用

Elasticsearch 的 NEST API 在 POSTMAN 提交时相同查询成功时不返回查询结果

c# - 需要帮助将事件驱动代码分成尊重 MVVM 模式的层

c# - 无法将 ASP.NET 应用程序连接到 Docker 上的 SQL Server

c# - 如何使用 Datatables.AspNet.Mvc5 进行服务器端排序

c# - 如何使用 ElasticSearch 5.x 的 NEST 流畅映射指定索引/字段分析器?

elasticsearch - 在 ElasticSearch Nest 客户端中创建自定义分析器

c# - 插入并返回插入的行数(非重复)和记录的 ID(新的或重复的)

c# - 无法在 Selenium 中启动 chrome 驱动程序

c# - 包含对面的实体 EF6