本文介绍如何使用ElasticsearchCRUD在Elasticsearch中创建父,子和孙子文档。 如果创建相互关联的文档,那么文件全部保存到Elasticsearch中的同一个分片很重要。 搜索性能更好,如果可以为搜索定义特定的分片。
当创建父文档和子文档关系时,父定义对于子文档是足够的。 这样可确保将子文档保存到同一分片中。 一旦使用了孙子文档,就需要一个路由定义,否则孙子文档不会总是被保存到同一个分片中,创建子文档的所有优点都将丢失。
步骤1:定义文档模型
在本应用程序中使用了LeagueCup,Team 和Player 类。 LeagueCup类是父类。 它有一个Team类的列表。 Team类有一个子Player类的列表。 我们希望将所有文档保存在同一个索引中,并确保将子文件和孙子节文档保存到同一个分片中。 子文档需要Key属性定义,以便ElasticsearchCrud知道哪个属性被用作_id定义。
步骤2:使用正确的映射创建索引
要使用映射创建索引,需要更改ElasticsearchCRUD中上下文的默认配置。 ElasticsearchSerializerConfiguration Config包含所有必需的配置。 我们希望将每个子文档保存为单独的映射或索引类型,并且还可以处理每种类型的所有子文档。 使用UserDefinedRouting,路由也被强制用于子文档。 这不是默认的,因为如果没有使用孙子文档,这不是必需的。 Elasticsearch中的默认配置将完整的子树保存为嵌套项,处理所有子项,并且不添加路由。
不同类型也需要映射定义。 默认情况下,每种类型将被保存到自己的索引中。 这是改变,所以关系中的所有类型都保存到相同的索引:leagues。
CreateIndexWithRouting方法创建一个新的索引,具有三种类型的映射。 context.CreateIndex()在三个不同的PUT请求中执行,每个类型一个。
具有父映射的创建索引如下发送:
发送第一个子类PUT请求如下所示。 路由仅使用必需属性定义。 不需要其他选项,因为如果使用属性,以下请求将发送到Elasticsearch,然后重新路由,这会导致性能损失。
孙子类映射PUT请求发送如下:
步骤3:添加LeagueCup文档
现在索引和类型映射存在,可以添加一个新的LeagueCup文件。
添加文档请求作为批量请求的一部分发送。 ElasticsearchCRUD在bulk请求中发送所有添加,更新和删除请求。 然后可以将不同的请求优化为单个请求。 context.SaveChanges()发送所有待处理的请求。
步骤4:添加Team文档
team 请求使用父类LeagueCup的父ID发送。
此请求使用父Id以及路由Id。 因为文档是一级的子级,所以两个id是相同的。
步骤5:添加Player文档
然后可以将player添加到team父级的索引中,并将路由添加到leagueCup顶级父级。
PUT请求再次以bulk 请求发送。 这当然可以与以前的请求一起发送,但是demo目的是单独发送的。
现在索引中存在3个文档,可以从搜索引擎中选择文档。 player文档的GET请求需要父Id和路由Id。
GetPlayer请求如下发送:
响应:
结论:
在Elasticsearch中定义和使用子文档和孙子文档非常简单。 如果要优化搜索性能,则需要将文档保存到同一个分片。 这是通过路由实现的。 如果只使用父文件和子文档,则只需要父Id。 如果同时更新和添加所有树结构,也可以使用嵌套文档。 所有数据结构都有优缺点。 应根据您的要求选择正确的。