2014-09-18 3 views
6

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

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

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

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

+0

Теперь можно использовать REINDEX через стороне сервера НЕСТ. –

ответ

13

NEST обеспечивает хороший Reindex метод можно использовать, хотя документация отсутствует. Я использовал его очень грубо и готово с помощью этого ad-hoc кода 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/

+0

Большое спасибо за это, я посмотрю, что я с этим могу сделать! – Gillespie

+1

Важная вещь для меня заключалась в вызове reindex.Subscribe() и просмотре исключений. Для меня это было безуспешно по двум причинам: 1) Индекс уже существует и 2) Текущий индекс не содержит никаких документов. – Sean

+1

Если я не создаю новый индекс в вызове reindex(), возникает ReindexException, почему это происходит? – Yasel

5

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

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

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

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

// 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; 
} 
0

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

Отсутствие кода Бена является поддержкой отношений между родителями и детьми. Вот мой код, чтобы установить, что:

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

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)); 
    }         
}