ElasticsearchCRUD使用(七)【Elasticsearch中的实时重建索引】

来源:互联网 发布:阿里云 黑洞中 编辑:程序博客网 时间:2024/05/29 14:13

该文章演示了如何使用ElasticsearchCRUD在Elasticsearch中进行现场重建索引。 reindex使用扫描并滚动获取数据,然后使用批量插入更新到新的索引。 reindex支持别名映射,使得可以进行实时索引。

设置文档搜索引擎和索引

AdventureWorks2012用于填充搜索引擎的数据。
从Entity Person添加person索引。
此代码创建一个新的索引persons_v1。 然后使用别名将其映射到persons

public void CreatePersonAliasForPersonV1Mapping(string alias){    using (var context = new ElasticsearchContext("http://localhost:9200/", _elasticsearchMappingResolver))    {        context.AliasCreateForIndex(alias, _elasticsearchMappingResolver.GetElasticSearchMapping(typeof(Person)).GetIndexForType(typeof(Person)));    }}

现在设置索引和别名。 Elasticsearch 已经准备好了一个实时重建索引。
这可以在这里查看: http://localhost:9200/_aliases 或者http://localhost:9200/_cat/aliases

{    "persons_v1": {    "aliases": {    "persons": {}    }  }}

步骤1:从索引persons_v1创建新索引persons_v2

从旧索引创建新的索引。 这可以直接执行。 当reindex正在执行时,可以添加新的文档或更新文档。 被删除的文件将不会被注意到。 因此,您应该使用一个布尔删除的字段。

reindex需要旧索引的索引和类型,还需要新的索引和新的索引类型。 如果您使用父/子文档索引,则必须对子文档重复此步骤。 ElasticsearchCRUD版本1.0.15之前,不支持父/子文档重建。

// - 这个时间戳通常是DateTime.UtcNow// - 因此,可以找到在reindex期间更新的所有索引DateTime beginDateTime = DateTime.UtcNow;var reindex = new ElasticsearchCrudReindex<Person, PersonV2>(    new IndexTypeDescription("persons_v1", "person"),     new IndexTypeDescription("persons_v2", "person"),     "http://localhost:9200");

reindex可以根据需要进行配置。 该方法使用扫描和滚动。 您可以更改默认设置,并在每个请求和响应中允许更多的文档。 您不应该让它太大,因为您不希望每个请求和响应发送500MB。

ScanAndScrollConfiguration定义每个滚动条保持打开的时间以及所有接下来的滚动条,并定义时间单位。 下面定义了5s。 如果有足够的时间,将从每个分片中获取1000个文档。
例如,如果您的索引中有5个分片,并且配置了足够的时间,并且有足够的文档,则下面的配置将在每个请求中获取5000个文档。

控制台日志用于显示进度

reindex.ScanAndScrollConfiguration = new ScanAndScrollConfiguration(new TimeUnitSecond(5), 1000);reindex.TraceProvider = new ConsoleTraceProvider(TraceEventType.Information);

reindex方法本身需要2个函数以及Json _search查询的Json内容。 使用小于范围的查询来在定义的DateTime之前选择所有文档。 如果需要不同的查询逻辑,可以根据需要进行定义。 如果您不担心更新或其他任何内容,您可以使用所有匹配项。

reindex也需要转换方法。 这就是进行reindex的原因。 在此示例中,删除的bool字段将添加到文档。 第二个函数用于定义文档_id

reindex.Reindex(    PersonReindexConfiguration.BuildSearchModifiedDateTimeLessThan(beginDateTime),     PersonReindexConfiguration.GetKeyMethod,     PersonReindexConfiguration.CreatePersonV2FromPerson);

Json内容生成方法BuildSearchModifiedDateTimeLessThan构建Json查询。 这是一个非常原始的实现,如果需要,您可以更加有说服力。

public static string BuildSearchModifiedDateTimeLessThan(DateTime dateTimeUtc){    return BuildSearchRange("lt", "modifieddate", dateTimeUtc);}//{//   "query" :  {//     "range": {  "modifieddate": { "lt":   "2003-12-29T00:00:00"  } }//  }//}private static string BuildSearchRange(string lessThanOrGreaterThan, string updatePropertyName, DateTime dateTimeUtc){    string isoDateTime = dateTimeUtc.ToString("s");    var buildJson = new StringBuilder();    buildJson.AppendLine("{");    buildJson.AppendLine("\"query\": {");    buildJson.AppendLine("\"range\": {  \"" + updatePropertyName + "\": { \"" + lessThanOrGreaterThan + "\":   \"" + isoDateTime + "\"  } }");    buildJson.AppendLine("}");    buildJson.AppendLine("}");    return buildJson.ToString();}

将旧文档类型转换为新文档类型的转换方法。

public static PersonV2 CreatePersonV2FromPerson(Person item){    return new PersonV2    {        BusinessEntityID = item.BusinessEntityID,        PersonType = item.PersonType,        NameStyle = item.NameStyle,        Title = item.Title,        FirstName = item.FirstName,        MiddleName = item.MiddleName,        LastName = item.LastName,        Suffix = item.Suffix,        EmailPromotion = item.EmailPromotion,        AdditionalContactInfo = item.AdditionalContactInfo,        Demographics = item.Demographics,        rowguid = item.rowguid,        ModifiedDate = item.ModifiedDate,        Deleted = false    };}Returns the _id property for the document _idpublic static object GetKeyMethod(Person person){    return person.BusinessEntityID;}

步骤2:更换别名persons 到 索引person_v2

现在别名从旧的索引切换到新的索引

reindex.SwitchAliasfromOldToNewIndex("persons");

别名指向persons_v2索引http://localhost:9200/_aliases

{    "persons_v1": {    "aliases": {}    },    "persons_v2": {    "aliases": {    "persons": {}    }    }}

步骤3:现在获得所有在REINDEXING和REINDEX上更新的文档

现在新的索引已经开始运行,所有在重新构建索引发生时更新的文档现在都被重新索引了。 它使用大于范围的查询搜索并返回大于开始DateTime的所有文档。

如果相同的文档在新索引中被更新,它将被覆盖。 再次,您可以决定这是否重要,并创建适当的查询搜索。

 // ---------------------------------------------------------//步骤3:现在可以获得所有在重新输入时更新的文档// ---------------------------------------------------------//注意:如果文档在此期间再次被更新,那么这个方法将被忽略。//如果需要,您必须检查新索引中项目的更新时间戳!reindex.Reindex(    PersonReindexConfiguration.BuildSearchModifiedDateTimeGreaterThan(beginDateTime),     PersonReindexConfiguration.GetKeyMethod,     PersonReindexConfiguration.CreatePersonV2FromPerson);

运行应用程序时,可以查看进度:
这里写图片描述

结论

Live reindex是Elasticsearch中的一个很棒的功能,在搜索引擎或NoSQL中,ElasticsearchCRUD 1.0.15中将支持父/子文档索引reindex。

0 0