如何使用NEST更新ElasticSearch索引中的现有文档?

时间:2014-05-22 01:09:19

标签: c# 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);
}

它不起作用。上面的代码生成语法错误。 有没有人知道使用ElasticSearch的C#NEST客户端执行此操作的正确方法?

5 个答案:

答案 0 :(得分:17)

我已使用以下方法使用NEST成功更新了我的Elasticsearch索引中的现有项目。请注意,在此示例中,您只需发送包含要更新的字段的部分文档。

    // 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 Update Unit Tests from the GitHub Source找到更多发送更新的方法示例。

答案 1 :(得分:13)

实际上对于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))

答案 2 :(得分:4)

Nest 2更新已包含ID字段的POCO:

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

答案 3 :(得分:0)

Nest 7.x中更好的解决方案:

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

答案 4 :(得分:0)

也使用Nest7.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;
 }

我使用的是Elastic Common Schema,因此这是用于更新的部分对象的示例:

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