首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何使用Nest Elasticsearch更新嵌套对象?

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

Stack Overflow用户
提问于 2019-01-31 17:23:05
回答 2查看 2.4K关注 0票数 1

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

代码语言:javascript
运行
复制
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; }
}

并绘制了以下地图:

代码语言:javascript
运行
复制
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)
                             )
                  )
             )

现在,我正在尝试更新嵌套对象中的name字段,并尝试使用脚本更新实现该字段,如下所示:

代码语言:javascript
运行
复制
        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)
                          );

但是,使用上面的查询,我无法更新嵌套对象,请告诉我如何使用_update_by_query api使用nest ES更新嵌套对象?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-02-01 13:55:35

最后,我发现了如何只更新特定嵌套对象的name属性,具体取决于它们的id,如下所示:

代码语言:javascript
运行
复制
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)
              );

在这里,生成的查询:

代码语言:javascript
运行
复制
 POST product/producttype/_update_by_query?conflicts=proceed&refresh=true 
{
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "query": {
              "term": {
                "productAttributes.id": {
                  "value": "563243f0-8fbb-4adf-a78d-1339e5971a43"
                }
              }
            },
            "path": "productAttributes"
          }
        }
      ]
    }
  },
  "script": {
    "params": {
        "id":"563243f0-8fbb-4adf-a78d-1339e5971a43",
        "name": "CPU"
    },
    "lang": "painless",
    "inline": "if (ctx._source.productAttributes != null){for (item in ctx._source.productAttributes){if (item.id == params.id) {item.name = params.name;}}}"
  }
}

那么,上面的查询是做什么的:

它首先搜索具有563243f0-8fbb-4adf-a78d-1339e5971a43 id的productAttribute的产品,然后在productAttributes嵌套对象上迭代,只更新该id的属性,然后再次对文档进行索引。

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

票数 1
EN

Stack Overflow用户

发布于 2019-02-01 10:16:55

看起来问题就在这里$"ctx._source.productAttributes= params.name;“

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

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

代码语言:javascript
运行
复制
        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")));
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54466057

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档