Как обновить существующий документ в индексе ElasticSearch с помощью NEST?

Я пытаюсь обновить существующий проиндексированный документ. У меня есть проиндексированные теги, заголовок и поле владельцев. Теперь, когда пользователь меняет заголовок, мне нужно найти и обновить документ внутри индекса.

Должен ли я обновлять и заменять весь документ или только поле заголовка?

public void UpdateDoc(ElasticsearchDocument doc)
{
 Uri localhost = new Uri("http://localhost:9200");
 var setting = new ConnectionSettings(localhost);
 setting.SetDefaultIndex("movies");
 var client = new ElasticClient(setting);

 IUpdateResponse resp = client.Update<ElasticsearchDocument, IndexedDocument>(
                                  d => d.Index("movies")
                                        .Type(doc.Type)
                                        .Id(doc.Id), doc);
}

Это просто не работает. Приведенный выше код генерирует синтаксическую ошибку. Кто-нибудь знает, как это сделать с помощью клиента C # NEST ElasticSearch?


person kheya    schedule 22.05.2014    source источник


Ответы (5)


Я успешно обновил существующие элементы в моем индексе Elasticsearch с помощью NEST, используя следующий метод. Обратите внимание, что в этом примере вам нужно отправить только часть документа с полями, которые вы хотите обновить.

    // Create partial document with a dynamic
    dynamic updateDoc = new System.Dynamic.ExpandoObject();
    updateDoc.Title = "My new title";

    var response = client.Update<ElasticsearchDocument, object>(u => u
        .Index("movies")
        .Id(doc.Id)
        .Document(updateDoc)
     );

Вы можете найти больше примеров способов отправки обновлений в Обновить модульные тесты NEST из источника GitHub.

person Paige Cook    schedule 22.05.2014
comment
updateDoc.Title = Мое новое название; неверно, дает синтаксическую ошибку. Я попробую несколько разных способов - person kheya; 22.05.2014
comment
динамический MyDynamic = новый System.Dynamic.ExpandoObject (); как я это сделал - person kheya; 22.05.2014
comment
Как получить doc.Id? Нужно ли мне сначала запросить документ? - person Tadej; 09.11.2017

Собственно для Nest 2 это:

dynamic updateFields = new ExpandoObject();
updateFields.IsActive = false;
updateFields.DateUpdated = DateTime.UtcNow;

await _client.UpdateAsync<ElasticSearchDoc, dynamic>(new DocumentPath<ElasticSearchDoc>(id), u => u.Index(indexName).Doc(updateFields))
person Jonathon Cwik    schedule 19.06.2016

Лучшее решение в Nest 7.x:

 await _client.UpdateAsync<ElasticSearchDoc>(doc.Id, u => u.Index("movies").Doc(new ElasticSearchDoc { Title = "Updated title!" }));
person Ali Bayat    schedule 13.11.2019

Чтобы Nest 2 обновил POCO, который уже включает поле ID:

 var task = client.UpdateAsync<ElasticsearchDocument>(
                    new DocumentPath<ElasticsearchDocument>(doc), u => 
                        u.Index(indexName).Doc(doc));
person gerosalesc    schedule 10.06.2016

также использую Nest 7.x.

Если вы хотите выполнить только частичное обновление, вы можете использовать этот метод, который отлично сработал для меня. Вы должны указать «T, K», где T - это полный объект, а K - частичный объект. Создание POCO для каждого частичного обновления - это своего рода переутомление и раздражение. Для этой проблемы вы можете использовать анонимный объект, например

 public bool PartialUpdate(string id, object entity)
 {
     var result = _elasticClient.Update<T, object>(DocumentPath<T>.Id(id), i => i.Index(_indexName).Doc(entity));

     return result.IsValid;
 }

Я использую эластичную общую схему, поэтому вот пример частичного объекта для обновления:

new
{
    Labels = new Dictionary<string, object>
    {
        { "EscalateTo", alert.AlertState == AlertState.Escalation ? escalationId : "" },
        { "EscalateFrom", alert.AlertState == AlertState.Descalation ? escalationId : "" },
    },
    Event = new
    {
        End = alert.WindowEnd,
        Duration = (alert.WindowEnd - storedAlert.StartTime.Value).Ticks
    }
};
person MaxThom    schedule 22.05.2020