Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/284.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用Nest Elasticsearch更新嵌套对象?_C#_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch_Nest - Fatal编程技术网 elasticsearch,nest,C#,elasticsearch,Nest" /> elasticsearch,nest,C#,elasticsearch,Nest" />

C# 如何使用Nest Elasticsearch更新嵌套对象?

C# 如何使用Nest Elasticsearch更新嵌套对象?,c#,elasticsearch,nest,C#,elasticsearch,Nest,我有product index,为了简单起见,它有两个字段Id和ProductAttributes作为嵌套对象,定义如下: public class ProductType { public Guid Id { get; set; } public List<ProductAttribute> ProductAttributes { get; set; } } public class ProductAttribute { public Guid Id

我有product index,为了简单起见,它有两个字段Id和ProductAttributes作为嵌套对象,定义如下:

public class ProductType
{
    public Guid Id { get; set; }

    public List<ProductAttribute> ProductAttributes { get; set; }
 }

public class ProductAttribute
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Value { get; set; }
}
        var scriptParams = new Dictionary<string, object>
                            {
                                {"name", "new name"}
                            };

        var result = elasticClient.UpdateByQuery<ProductType>(u => u
                              .Script(sn => sn
                                   .Inline(
                                          $"ctx._source.productAttributes= params.name;" 
                                      )
                                  .Params(scriptParams)
                              )
                              .Conflicts(Conflicts.Proceed)
                              .Refresh(true)
                          );
var result = elasticClient.UpdateByQuery<ProductType>(u => u
                  .Query(q => q
                        .Nested(n => n
                          .Path(Infer.Field<ProductType>(ff => ff.ProductAttributes))
                          .Query(nq => nq
                              .Term(Infer.Field<ProductType>(ff => ff.ProductAttributes.First().Id), productAttributeId)
                          )
                        )
                  )
                  .Script(ss => ss.Inline("if (ctx._source.productAttributes != null){for (item in ctx._source.productAttributes){if (item.id == params.id) {item.name = params.name;}}}")
                     .Params(new Dictionary<string, object>()
                     {
                         {"id", productAttributeId},
                         {"name", productAttributeName}
                     }).Lang("painless")
                  )
                  .Conflicts(Conflicts.Proceed)
                  .Refresh(true)
              );
公共类ProductType
{
公共Guid Id{get;set;}
公共列表ProductAttributes{get;set;}
}
公共类ProductAttribute
{
公共Guid Id{get;set;}
公共字符串名称{get;set;}
公共字符串值{get;set;}
}
以及以下映射:

elasticClient.CreateIndex("product", i => i
       .Settings(s => s
                 .NumberOfShards(2)
                 .NumberOfReplicas(0)
                 )
                 .Mappings(m => m
                   .Map<ProductType>(map => map
                         .AutoMap()
                         .Properties(p => p
                          .Nested<ProductAttribute>(n => n
                            .Name(c => c.ProductAttributes)
                            .AutoMap()
                            .Properties(nc => nc
                               .Keyword(t => t
                                   .Name(nn => nn.Name)
                                   )
                              .Keyword(t => t
                                .Name(nn => nn.Value)
                             )
                  )
             )
elasticClient.CreateIndex(“产品”,i=>i
.Settings(s=>s
.NumberOfShard(2)
.numberofreplications(0)
)
.Mappings(m=>m
.Map(Map=>Map
.AutoMap()
.Properties(p=>p
.Nested(n=>n
.Name(c=>c.ProductAttributes)
.AutoMap()
.Properties(nc=>nc
.Keyword(t=>t
.Name(nn=>nn.Name)
)
.Keyword(t=>t
.Name(nn=>nn.Value)
)
)
)
现在,我尝试更新嵌套对象中的名称字段,并尝试使用脚本更新实现该字段,如下所示:

public class ProductType
{
    public Guid Id { get; set; }

    public List<ProductAttribute> ProductAttributes { get; set; }
 }

public class ProductAttribute
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Value { get; set; }
}
        var scriptParams = new Dictionary<string, object>
                            {
                                {"name", "new name"}
                            };

        var result = elasticClient.UpdateByQuery<ProductType>(u => u
                              .Script(sn => sn
                                   .Inline(
                                          $"ctx._source.productAttributes= params.name;" 
                                      )
                                  .Params(scriptParams)
                              )
                              .Conflicts(Conflicts.Proceed)
                              .Refresh(true)
                          );
var result = elasticClient.UpdateByQuery<ProductType>(u => u
                  .Query(q => q
                        .Nested(n => n
                          .Path(Infer.Field<ProductType>(ff => ff.ProductAttributes))
                          .Query(nq => nq
                              .Term(Infer.Field<ProductType>(ff => ff.ProductAttributes.First().Id), productAttributeId)
                          )
                        )
                  )
                  .Script(ss => ss.Inline("if (ctx._source.productAttributes != null){for (item in ctx._source.productAttributes){if (item.id == params.id) {item.name = params.name;}}}")
                     .Params(new Dictionary<string, object>()
                     {
                         {"id", productAttributeId},
                         {"name", productAttributeName}
                     }).Lang("painless")
                  )
                  .Conflicts(Conflicts.Proceed)
                  .Refresh(true)
              );
var scriptParams=新字典
{
{“名称”,“新名称”}
};
var result=elasticClient.UpdateByQuery(u=>u
.Script(sn=>sn
.内联(
$“ctx.\u source.productAttributes=params.name;”
)
.Params(脚本参数)
)
.冲突(冲突。继续)
.刷新(真)
);

但是使用上面的查询我无法更新嵌套对象,您能告诉我如何使用嵌套ES使用\u update\u by\u queryapi更新嵌套对象吗?

Look likes问题在于$“ctx.\u source.productAttributes=params.name;”

productAttributes是一个对象(嵌套对象),params.name是一个值(字符串),这就是查询响应中的内容

不确定您到底想做什么,如果您的要求是更新所有productAttributes元素的名称,您可以尝试以下方法:

        var result = elasticClient.UpdateByQuery<ProductType>(u => u
            .Index("product")
            .Script(ss => ss.Source("for(int i=0; i<ctx._source.productAttributes.size(); i++){HashMap myKV = ctx._source.productAttributes.get(i);myKV.put(params.item.fieldName, params.item.fieldValue);}")
                        .Params(d => d.Add("item", new Dictionary<string, object>()
                        {
                            {"fieldName", "name" },
                            {"fieldValue", "new name" }
                        })).Lang("painless")));
var result=elasticClient.UpdateByQuery(u=>u
.指数(“产品”)

.Script(ss=>ss.Source(“for(int i=0;i)最后,我发现了如何根据特定嵌套对象的id仅更新其name属性,如下所示:

public class ProductType
{
    public Guid Id { get; set; }

    public List<ProductAttribute> ProductAttributes { get; set; }
 }

public class ProductAttribute
{
    public Guid Id { get; set; }

    public string Name { get; set; }

    public string Value { get; set; }
}
        var scriptParams = new Dictionary<string, object>
                            {
                                {"name", "new name"}
                            };

        var result = elasticClient.UpdateByQuery<ProductType>(u => u
                              .Script(sn => sn
                                   .Inline(
                                          $"ctx._source.productAttributes= params.name;" 
                                      )
                                  .Params(scriptParams)
                              )
                              .Conflicts(Conflicts.Proceed)
                              .Refresh(true)
                          );
var result = elasticClient.UpdateByQuery<ProductType>(u => u
                  .Query(q => q
                        .Nested(n => n
                          .Path(Infer.Field<ProductType>(ff => ff.ProductAttributes))
                          .Query(nq => nq
                              .Term(Infer.Field<ProductType>(ff => ff.ProductAttributes.First().Id), productAttributeId)
                          )
                        )
                  )
                  .Script(ss => ss.Inline("if (ctx._source.productAttributes != null){for (item in ctx._source.productAttributes){if (item.id == params.id) {item.name = params.name;}}}")
                     .Params(new Dictionary<string, object>()
                     {
                         {"id", productAttributeId},
                         {"name", productAttributeName}
                     }).Lang("painless")
                  )
                  .Conflicts(Conflicts.Proceed)
                  .Refresh(true)
              );
那么,上述查询的作用是什么:

它首先搜索productAttribute具有563243f0-8fbb-4adf-a78d-1339e5971a43id的产品,然后迭代productAttributes嵌套对象以仅更新具有该id的属性,然后再次为文档重新编制索引


我希望我的回答能帮助其他在Elasticsearch中面临更新嵌套对象问题的人。

您的查询添加了新的productAttribute而不是更新了特定的productAttribute。我正在尝试只更新特定productAttributes的属性名称,并保持id和值不变