c# - ElasticSearch更新到子文档而不更新父文档

标签 c# elasticsearch nest

当子文档的属性发生更改时,ElasticSearch中是否可以自动更新所有父文档?也许我正在跟踪我如何使用ElasticSearch。编码:

        var child = new Child
        {
            Id = Guid.NewGuid(),
            Name = "Child"
        };

        var parent = new Parent
        {
            Id = Guid.NewGuid(),
            Name = "Parent",
            Child = child
        };

        var nestedResponse = client.CreateIndex("index", i => i
            .Mappings(m => m
                .Map<Parent>(map => map
                    .AutoMap()
                    .Properties(ps => ps
                        .Nested<Child>(n => n
                            .Name(p => p.Child)
                            .AutoMap()
                        )
                    )
                )
            )
        );

        var indexResult = client.Index<Parent>(parent);
        indexResult = client.Index<Child>(child);

        var reloadedParent = client.Get<Parent>(parent.Id.ToString()).Source;
        var childName = reloadedParent.Child.Name;
        child.Name = "child changed";
        var updateRequest = new UpdateRequest<Child, Child>("index", typeof(Child), child.Id);
        updateRequest.Doc = child;

        var reindexResult = client.Update<Child>(updateRequest);

        var reloadedParentAfterChildChange = client.Get<Parent>(parent.Id.ToString()).Source;
        var childChangedName = reloadedParentAfterChildChange.Child.Name;

        Assert.AreEqual(child.Name, childChangedName);

    }
}

public class Parent
{
    public Guid Id { get; set; }
    public string Name { get; set; }
    public Child Child { get; set; }
}

public class Child
{
    public Guid Id { get; set; }
    public string Name { get; set; }
}

child 可以属于许多不同的 parent 。有什么办法可以将对子项的更改传播到包含该子项的所有父项?我正在使用C#的Nest客户端。

最佳答案

你在做什么不是很正确。

  • 在映射中,您将Child属性设置为嵌套类型,但随后又对parentchild进行了索引。

    嵌套类型在嵌套的类型上建立索引,也就是说,表示Childparent属性的json被索引为父json文档的一部分。

    在Elasticsearch中可能有一个Parent/Child relationship,其中有一个 parent 有很多 child ,这听起来像您需要反转模型中的“ parent / child ”角色才能使用。
  • 编制索引之后,您将获得parent文档的源代码,在父级上更改子级的子级名称,然后更新已建立索引的子级文档,而无需使用该子级更新parent

    许多文档可以具有相同的嵌套文档值,但是这些文档之间没有关系,因此更新值将需要对每个文档进行更新。这可以通过Update By Query API完成。

  • 这是一个示范的例子。在生产中,您可能不想禁用直接流式传输,注销所有请求/响应,在每次操作后调用刷新等。
    void Main()
    {
        var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
        var defaultIndex = "default-index";
        var connectionSettings = new ConnectionSettings(pool)
                .DefaultIndex(defaultIndex)
                .PrettyJson()
                .DisableDirectStreaming()
                .OnRequestCompleted(response =>
                    {
                        // log out the request
                        if (response.RequestBodyInBytes != null)
                        {
                            Console.WriteLine(
                                $"{response.HttpMethod} {response.Uri} \n" +
                                $"{Encoding.UTF8.GetString(response.RequestBodyInBytes)}");
                        }
                        else
                        {
                            Console.WriteLine($"{response.HttpMethod} {response.Uri}");
                        }
    
                        Console.WriteLine();
    
                        // log out the response
                        if (response.ResponseBodyInBytes != null)
                        {
                            Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
                                     $"{Encoding.UTF8.GetString(response.ResponseBodyInBytes)}\n" +
                                     $"{new string('-', 30)}\n");
                        }
                        else
                        {
                            Console.WriteLine($"Status: {response.HttpStatusCode}\n" +
                                     $"{new string('-', 30)}\n");
                        }
                    });
    
        var client = new ElasticClient(connectionSettings);
    
        if (client.IndexExists(defaultIndex).Exists)
            client.DeleteIndex(defaultIndex);
    
        var child = new Child
        {
            Id = Guid.NewGuid(),
            Name = "Child"
        };
    
        var parent = new Parent
        {
            Id = Guid.NewGuid(),
            Name = "Parent",
            Child = child
        };
    
        var anotherParent = new Parent
        {
            Id = Guid.NewGuid(),
            Name = "Another Parent",
            Child = child
        };
    
        var nestedResponse = client.CreateIndex(defaultIndex, i => i
            .Mappings(m => m
                .Map<Parent>(map => map
                    .AutoMap()
                    .Properties(ps => ps
                        .String(s => s
                            .Name(nn => nn.Id)
                            .NotAnalyzed()
                        )
                        .Nested<Child>(n => n
                            .Name(p => p.Child)
                            .AutoMap()
                            .Properties(p => p
                                .String(s => s
                                    .Name(nn => nn.Id)
                                    .NotAnalyzed()
                                )
                            )
                        )
                    )
                )
            )
        );
    
        var indexResult = client.Index<Parent>(parent);
        indexResult = client.Index<Parent>(anotherParent);
    
        var fetchedParent = client.Get<Parent>(parent.Id).Source;
        var fetchedAnotherParent = client.Get<Parent>(anotherParent.Id).Source;
    
        client.Refresh(defaultIndex);
    
        var update = client.UpdateByQuery<Parent>(u => u
            .Query(q => q
                .Nested(n => n
                    .Path(p => p.Child)
                    .Query(qq => qq
                        .Term(t => t.Child.Id, child.Id)
                    )
                )
            )
            .Script("ctx._source.child.name='New Child Name'")
            .Conflicts(Conflicts.Abort)
            .WaitForCompletion()
            .Refresh()
        );
    
        fetchedParent = client.Get<Parent>(parent.Id).Source;
        fetchedAnotherParent = client.Get<Parent>(anotherParent.Id).Source;
    }
    
    
    public class Parent
    {
        public Guid Id { get; set; }
    
        public string Name { get; set; }
    
        public Child Child { get; set;} 
    }
    
    public class Child
    {
        public Guid Id { get; set; }
    
        public string Name { get; set; } 
    }
    

    关于c# - ElasticSearch更新到子文档而不更新父文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41882928/

    相关文章:

    c# - 当您使用 async-await 时,我在何处定义任务以及在何处等待它是否重要?

    c# - Entity Framework 5.0。我的查询有什么问题?

    elasticsearch - 数据转换和Logstash

    elasticsearch - Elasticsearch NEST翻译

    c# - ElasticSearch NEST 7.x 将项目附加到现有文档对象数组属性

    c# - SQLiteConnection.BeginTransaction() 已弃用

    python - 为什么在Elastic Search中的聚合中实现分页时 'from'关键字变得无法识别

    elasticsearch - 在Elasticsearch中使用聚合搜索geo_distance

    c# - Entity Framework 将数千个对象传输到 Elastic Search

    c# - 查看WP7是否处于静音模式