nest for elasticsearch版本2.0.0.0嵌套对象的部分更新

时间:2016-09-27 10:39:39

标签: c# elasticsearch nest

说,我有一些POCO如下。

public class Graph
{
    public string Id { get; set; } // Indexed by this
    public List<Node> NodeList { get; set; }
}

public class Node
{
    public string Id { get; set; }
    public string Name { get; set; }
    public List<Edge> EdgeList { get; set; }
}

public class Edge
{
    public string Id { get; set; }
    public double Cost { get; set; }
}

部分更新我的Graph时 我想在Node NodeList中找到现有的Id,并更新它的NameEdge属性。我想在我的Node中添加新的NodeList个对象。只想更新现有的。

Sofar我试过了:

public void UpdateGraph(string index, Graph graph)
{
    var docPath = new DocumentPath<Graph>(graph.Id).Index(index);
    try
    {
        var updateResp = client.Update<Graph, Graph>(docPath, searchDescriptor => searchDescriptor
            .Doc(graph)    
            .RetryOnConflict(4)
            .Refresh(true)
        );
    }
}

在我目前的实施中,您可以看到我所做的一切正在取代 旧的Graph对象。但我想部分更新我的Graph对象。我想发送Node对象列表作为参数, 在NodeList中查找这些内容并仅更新Node个对象。

也许有点如下,

public void UpdateGraph(string index, List<Node> node)
{
    //Code here
}

1 个答案:

答案 0 :(得分:1)

由于NodeListList<Node>,因此无法进行部分更新,因为提供的值会替换现有值。

但是,您可以使用optimistic concurrency control

  1. 获取现有文件
  2. 在您的应用程序中进行更改
  3. 使用乐观并发的get请求中的版本号将已更改的文档索引回Elasticsearch
  4. 以下内容将起作用

    var getResponse = client.Get<Graph>("graph-id");
    
    var graph = getResponse.Source;
    var node = graph.NodeList.First(n => n.Id == "node-id");  
    
    // make changes to the node
    node.Name = "new name";
    node.EdgeList.First().Cost = 9.99;
    
    var indexResponse = client.Index(graph, i => i
        // specify the version from the get request
        .Version(getResponse.Version)
    );
    

    如果在get和index调用之间更改了Graph,那么将在索引调用上返回409响应。

    如果您经常需要彼此独立更新NodeEdge,您可以决定使用Parent/Child relationships对其进行建模,这样您就可以更新而无需退回对象图并索引更改。