예제 #1
0
        /// <summary>
        /// This will rebuild an entire index alias behind the scenes with no downtime. It creates a new index
        /// and populates it then uses Elasticsearch's hot-swapping technique to bring it online.
        /// </summary>
        public async static Task RebuildIndexWithHotSwapAsync(
            this IElasticLowLevelClient client,
            string alias,
            JObject indexMapping,
            Func <Task <IEnumerable <BulkIndexingDoc> > > reader,
            CancellationToken ctx = default(CancellationToken))
        {
            var deletableIndices = JArray.Parse((await client.CatAliasesAsync <StringResponse>(alias, new CatAliasesRequestParameters {
                Format = "json"
            }, ctx)).Body)
                                   .Select(x => new
            {
                alias = x.Value <string>("alias"),
                index = x.Value <string>("index")
            })
                                   .ToList();

            var index = GenerateUniqueIndexNameForAlias(alias);

            await client.IndicesCreateAsync <StringResponse>(index, PostData.String(indexMapping?.ToString()), ctx : ctx);

            while (!ctx.IsCancellationRequested)
            {
                // TODO: If an exception is thrown, delete the half-created index
                var docs = await reader();

                if (ctx.IsCancellationRequested || !docs.Any())
                {
                    break;
                }

                var body         = docs.SelectMany(doc => doc.ToLines().Select(x => x.ToString(Formatting.None)));
                var bulkResponse = await client.BulkAsync <StringResponse>(index, PostData.MultiJson(body));

                ThrowOnPartialBulkSuccess(bulkResponse);
            }

            if (ctx.IsCancellationRequested)
            {
                return;
            }

            var actions = deletableIndices.Select(idx => (object)new
            {
                remove = new { idx.index, idx.alias }
            }).ToList();

            actions.Add(new { add = new { index, alias } });

            // This is the hot-swap. The actions in the list are performed atomically
            await client.IndicesUpdateAliasesForAllAsync <StringResponse>(PostData.String(JObject.FromObject(new
            {
                actions
            }).ToString()), ctx : ctx);

            if (deletableIndices.Any())
            {
                await client.IndicesDeleteAsync <StringResponse>(string.Join(",", deletableIndices.Select(x => x.index)), ctx : ctx);
            }
        }
예제 #2
0
        public static async Task <string> ReIndex <T>(List <T> data) where T : Entity, ISearcheable, new()
        {
            var targetType = typeof(T).Name.ToLower();
            await _lowlevelClient.IndicesDeleteAsync <StringResponse>(targetType);

            foreach (var post in data)
            {
                var indexObject = post.GetIndexObject();
                await _lowlevelClient.IndexAsync <StringResponse>(targetType, targetType,
                                                                  indexObject.Id, PostData.Serializable(indexObject));
            }

            return($"{data.Count} reindexed");
        }