Примеры переиндексации NEST Elasticsearch

моя цель состоит в том, чтобы переиндексировать индекс с 10 миллионами осколков с целью изменения сопоставления полей, чтобы облегчить анализ важных терминов.

Моя проблема в том, что у меня возникли проблемы с использованием библиотеки NEST для выполнения переиндексации, а документация (очень) ограничена. Если возможно, мне нужен пример следующего использования:

http://nest.azurewebsites.net/nest/search/scroll.html

http://nest.azurewebsites.net/nest/core/bulk.html


person Gillespie    schedule 18.09.2014    source источник
comment
Теперь можно использовать переиндексацию на стороне сервера через NEST.   -  person Ben Wilde    schedule 15.12.2016


Ответы (3)


NEST предоставляет хороший метод Reindex, который вы можете использовать, хотя документация отсутствует. Я использовал его очень грубым образом с этим специальным кодом WinForms.

    private ElasticClient client;
    private double count;

    private void reindex_Completed()
    {
        MessageBox.Show("Done!");
    }

    private void reindex_Next(IReindexResponse<object> obj)
    {
        count += obj.BulkResponse.Items.Count();
        var progress = 100 * count / (double)obj.SearchResponse.Total;
        progressBar1.Value = (int)progress;
    }

    private void reindex_Error(Exception ex)
    {
        MessageBox.Show(ex.ToString());
    }

    private void button1_Click(object sender, EventArgs e)
    {
        count = 0;

        var reindex = client.Reindex<object>(r => r.FromIndex(fromIndex.Text).NewIndexName(toIndex.Text).Scroll("10s"));

        var o = new ReindexObserver<object>(onError: reindex_Error, onNext: reindex_Next, completed: reindex_Completed);
        reindex.Subscribe(o);
    }

И я только что нашел запись в блоге, в которой показано, как это сделать: http://thomasardal.com/elasticsearch-migrations-with-c-and-nest/

person batwad    schedule 18.09.2014
comment
Большое спасибо за это, я посмотрю, что я могу сделать с ним! - person Gillespie; 18.09.2014
comment
Важным для меня был вызов reindex.Subscribe() и наблюдение за генерируемыми исключениями. У меня это не получалось по двум причинам: 1) индекс уже существует и 2) текущий индекс не содержит никаких документов. - person Sean; 15.01.2015
comment
Если я не создам новый индекс в вызове reindex(), возникнет ReindexException, почему это происходит? - person Yasel; 20.05.2015
comment
или попробуйте nuget.org/packages/ElasticsearchCRUD и подпишитесь на этот блог damienbod.com/2014/11/07/live-reindex-in-elasticsearch - person SSED; 03.06.2016

К сожалению, реализация NEST не совсем то, что я ожидал. На мой взгляд, он немного переработан для, возможно, наиболее распространенного варианта использования.

Многие люди просто хотят обновить свои карты с нулевым временем простоя...

В моем случае я уже позаботился о создании индекса со всеми его настройками и отображениями, но NEST настаивает на том, что он должен создавать новый индекс при переиндексации. Это среди многих других вещей. Слишком много других вещей.

Я обнаружил, что гораздо проще просто реализовать напрямую, поскольку в NEST уже есть методы Search, Scroll и Bulk. (это взято из реализации NEST):

// Assuming you have already created and setup the index yourself
public void Reindex(ElasticClient client, string aliasName, string currentIndexName, string nextIndexName)
{
    Console.WriteLine("Reindexing documents to new index...");
    var searchResult = client.Search<object>(s => s.Index(currentIndexName).AllTypes().From(0).Size(100).Query(q => q.MatchAll()).SearchType(SearchType.Scan).Scroll("2m"));
    if (searchResult.Total <= 0)
    {
        Console.WriteLine("Existing index has no documents, nothing to reindex.");
    }
    else
    {
        var page = 0;
        IBulkResponse bulkResponse = null;
        do
        {
            var result = searchResult;
            searchResult = client.Scroll<object>(s => s.Scroll("2m").ScrollId(result.ScrollId));
            if (searchResult.Documents != null && searchResult.Documents.Any())
            {
                searchResult.ThrowOnError("reindex scroll " + page);
                bulkResponse = client.Bulk(b =>
                {
                    foreach (var hit in searchResult.Hits)
                    {
                        b.Index<object>(bi => bi.Document(hit.Source).Type(hit.Type).Index(nextIndexName).Id(hit.Id));
                    }

                    return b;
                }).ThrowOnError("reindex page " + page);
                Console.WriteLine("Reindexing progress: " + (page + 1) * 100);
            }

            ++page;
        }
        while (searchResult.IsValid && bulkResponse != null && bulkResponse.IsValid && searchResult.Documents != null && searchResult.Documents.Any());
        Console.WriteLine("Reindexing complete!");
    }

    Console.WriteLine("Updating alias to point to new index...");
    client.Alias(a => a
        .Add(aa => aa.Alias(aliasName).Index(nextIndexName))
        .Remove(aa => aa.Alias(aliasName).Index(currentIndexName)));

    // TODO: Don't forget to delete the old index if you want
}

И метод расширения ThrowOnError, если вы этого хотите:

public static T ThrowOnError<T>(this T response, string actionDescription = null) where T : IResponse
{
    if (!response.IsValid)
    {
        throw new CustomExceptionOfYourChoice(actionDescription == null ? string.Empty : "Failed to " + actionDescription + ": " + response.ServerError.Error);
    }

    return response;
}
person Ben Wilde    schedule 19.01.2016

Я второй ответ Бена Уайльда выше. Лучше иметь полный контроль над созданием индекса и процессом переиндексации.

Чего не хватает в коде Бена, так это поддержки отношений родитель/потомок. Вот мой код, чтобы исправить это:

Замените следующие строки:

foreach (var hit in searchResult.Hits)
{
    b.Index<object>(bi => bi.Document(hit.Source).Type(hit.Type).Index(nextIndexName).Id(hit.Id));
}

С этим:

foreach (var hit in searchResult.Hits)
{
    var jo = hit.Source as JObject;
    JToken jt;
    if(jo != null && jo.TryGetValue("parentId", out jt))
    {
        // Document is child-document => add parent reference
        string parentId = (string)jt;
        b.Index<object>(bi => bi.Document(hit.Source).Type(hit.Type).Index(nextIndexName).Id(hit.Id).Parent(parentId));
    }
    else
    {
        b.Index<object>(bi => bi.Document(hit.Source).Type(hit.Type).Index(nextIndexName).Id(hit.Id));
    }                                
}
person Jonas Code North    schedule 14.05.2016