【问题标题】:How do I update an existing document inside ElasticSearch index using NEST?如何使用 NEST 更新 ElasticSearch 索引中的现有文档?
【发布时间】:2014-05-22 01:09:19
【问题描述】:

我正在尝试更新现有的索引文档。 我有索引标签、标题和所有者字段。现在当用户更改标题时,我需要在索引中查找并更新文档。

我应该更新和替换整个文档还是只替换标题字段?

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 客户端执行此操作的正确方法?

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

    我已经使用如下方法成功地使用 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 中找到更多发送更新方法的示例。

    【讨论】:

    • updateDoc.Title = "我的新标题";不正确,它给出了语法错误。我会尝试几种不同的方法
    • 动态 MyDynamic = new System.Dynamic.ExpandoObject();我是怎么做到的
    • 如何获得doc.Id?我必须先查询文档吗?
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

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

          我使用的是 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
              }
          };
          

          【讨论】:

            猜你喜欢
            • 2020-09-11
            • 2016-06-09
            • 2020-04-18
            • 1970-01-01
            • 1970-01-01
            • 2023-04-07
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多