【问题标题】:Update nested field in an index of ElasticSearch with Java API使用 Java API 更新 ElasticSearch 索引中的嵌套字段
【发布时间】:2014-04-29 11:47:14
【问题描述】:

我在 elasticsearch 上使用 Java API 进行 CRUD 操作。

我有一个带有嵌套字段的类型,我想更新这个字段。

这是我的类型映射:

"enduser": {
            "properties": {
                "location": {
                    "type": "nested",
                    "properties":{
                        "point":{"type":"geo_point"}
                    }
                }
            }
        }

当然,我的最终用户类型会有其他参数。

现在我想在我的嵌套字段中添加这个文档:

"location":{
          "name": "London",
           "point": "44.5, 5.2"
}

我正在搜索有关如何更新嵌套文档的文档,但找不到任何内容。例如,我在一个字符串中有前一个 JSON 对象(我们称这个字符串为 json)。我尝试了以下代码,但似乎无法正常工作:

params.put("location", json);
client.prepareUpdate(index, ElasticSearchConstants.TYPE_END_USER,id).setScript("ctx._source.location = location").setScriptParams(params).execute().actionGet();

我从 elasticsearch 得到一个解析错误。有谁知道我做错了什么?

【问题讨论】:

    标签: java json elasticsearch


    【解决方案1】:

    您不需要脚本,只需更新它。

        UpdateRequestBuilder br = client.prepareUpdate("index", "enduser", "1");
        br.setDoc("{\"location\":{ \"name\": \"london\", \"point\": \"44.5,5.2\" }}".getBytes());
        br.execute();
    

    【讨论】:

    • 嘿。事实上,这个解决方案是可能的,但我收到的文档总是不同的,所以我不能硬编码它,我用 setDoc 尝试了很多方法,但没有一个能正常工作。最后上面的脚本使用是我的问题的解决方案
    • 根据你的例子,你有 json - 它只是 json.toString().getBytes() 而不是硬编码的值......避免调用应该使整体速度更快。
    【解决方案2】:

    我试图重现您的情况,并通过使用 .setScript 方法的另一种方式解决了它。

    您现在的更新请求如下所示:

    client.prepareUpdate(index, ElasticSearchConstants.TYPE_END_USER,id).setScript("ctx._source.location =" + json).execute().actionGet()
    

    希望对你有所帮助。

    【讨论】:

      【解决方案3】:

      我不确定您使用的是哪个 ES 版本,但以下解决方案在 2.2.0 上非常适合我。我必须为新闻文章存储有关命名实体的信息。我想如果你希望在你的情况下有多个位置,它也适合你。

      这是我要更新的嵌套对象

      "entities" : [
          {
              "disambiguated" : {
                  "entitySubTypes" : [],
                  "disambiguatedName" : "NameX"
              },
              "frequency" : 1,
              "entityType" : "Organization",
              "quotations" : ["...", "..."],
              "name" : "entityX"
          },
          {
              "disambiguated" : {
                  "entitySubType" : ["a",  "b" ],
                  "disambiguatedName" : "NameQ"
              },
              "frequency" : 5,
              "entityType" : "secondTypeTest",
              "quotations" : [ "...", "..."],
              "name" : "entityY"
          }
      ],
      

      这是代码

      UpdateRequest updateRequest = new UpdateRequest();
      updateRequest.index(indexName);
      updateRequest.type(mappingName);
      updateRequest.id(url); // docID is a url
      XContentBuilder jb = XContentFactory.jsonBuilder();
      jb.startObject(); // article
      jb.startArray("entities"); // multiple entities
      
      for ( /*each namedEntity*/) {
      
      jb.startObject() // entity
         .field("name", name)
         .field("frequency",n)
         .field("entityType", entityType)
         .startObject("disambiguated") // disambiguation
         .field("disambiguatedName", disambiguatedNameStr)
         .field("entitySubTypes", entitySubTypeArray) // multi value field
         .endObject() // disambiguation
         .field("quotations", quotationsArray) // multi value field
         .endObject(); // entity
      
      }
      
      jb.endArray(); // array of nested objects
      b.endObject(); // article
      updateRequest.doc(jb);
      

      Blblblblblblbl 的答案对我 atm 不起作用,因为我们的服务器中未启用脚本。我还没有尝试过 Bask 的答案——Alcanzar 让我很难过,因为我应该无法正确地制定 setDoc 接收到的 json 字符串。我不断收到错误,要么我使用的是对象而不是字段,反之亦然。我还尝试使用 doc{} 包装 json 字符串,如 here 所示,但我没能成功。正如您所提到的,很难理解如何在 ES 的 java API 中制定 curl 语句。

      【讨论】:

      • for ( /*each namedEntity*/) { 这个值是多少?
      【解决方案4】:

      使用 Java API 更新数组列表和对象值的简单方法。

      UpdateResponse update = client.prepareUpdate("indexname","type",""+id)
              .addScriptParam("param1", arrayvalue)
               .addScriptParam("param2", objectvalue)
              .setScript("ctx._source.field1=param1;ctx._source.field2=param2").execute()
                      .actionGet(); 
      
      arrayvalue-[
      {
          "text": "stackoverflow",
          "datetime": "2010-07-27T05:41:52.763Z",
          "obj1": {
              "id": 1,
              "email": "sa@gmail.com",
              "name": "bass"
              },
          "id": 1,
      }
      
      object value -
      "obj1": {
          "id": 1,
          "email": "sa@gmail.com",
          "name": "bass"
      }
      

      【讨论】:

        猜你喜欢
        • 2021-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多