【问题标题】:Can i add tags to a "deeper" key in an Elastic Search document?我可以将标签添加到 Elastic Search 文档中的“更深”键吗?
【发布时间】:2021-03-25 06:32:46
【问题描述】:

我有带有标签的产品,标签在标签类型中。

这是我添加到索引中的示例文档

 {
        "_index" : "products",
        "_type" : "_doc",
        "_id" : "1219",
        "_score" : 1.0,
        "_source" : {
          "id" : "1219",
          "product_no" : "26426492261",
          "merchant_id" : 11,
          "name" : "Apple »Magic Keyboard für das 12,9\" iPad Pro (4. Generation)« iPad-Tastatur",
          "category" : "Technik>Multimedia>Zubehör>Tastatur>iPad Tastatur",
          "deep_link" : "https://foo",
          "short_description" : null,
          "long_description" : "Apple:",
          "brand" : "Apple",
          "merchant_image_url" : "http://something",
          "tagtypes" : [
            [
              {
                "Memory" : [ ]
              }
            ]
          ]
        }
      },

标签类型“内存”是在索引产品时动态创建的。

我试图给那个键添加标签

 //attach tags also to ES
                        $params = [
                            'index' => 'products',
                            'id' => $product['_id'],
                            'body' => [
                                'script' => [
                                    'source' => 'if (!ctx._source.tagtypes.'.$tagType->name.'.contains(params.tag)) { ctx._source.tagtypes.'.$tagType->name.'.add(params.tag) }',
                                    'lang' => 'painless',
                                    'params' => [
                                        'tag' => $tag->value
                                    ]
                                ]
                            ]

                        ];

但我收到类似的错误

{"error":{"root_cause":[{"type":"illegal_argument_exception","reason":"failed to execute script"}],"type":"illegal_argument_exception","reason":"failed to execute script","caused_by":{"type":"script_exception","reason":"runtime error","script_stack":["if (!ctx._source.tagtypes[\"Memory\"].contains(params.tag)) { "," ^---- HERE"],"script":"if (!ctx._source.tagtypes[\"Memory\"].contains(params.tag)) { ctx._source.tagtypes[\"Memory\"].add(params.tag) }","lang":"painless","position":{"offset":16,"start":0,"end":60},"caused_by":{"type":"wrong_method_type_exception","reason":"cannot convert MethodHandle(List,int)int to (Object,String)String"}}},"status":400}

谁能帮我解决这个问题。我找不到任何关于它的文档,因为这些示例通常太基础了。

通常可以像这样保存到“更深的键”吗? 或者我可以将“标签”创建为简单列表(没有任何深度)

提前致谢 阿德里安!

【问题讨论】:

    标签: php elasticsearch tags


    【解决方案1】:

    您的字段tagtypes 是一组对象数组,这些对象本身包含一键数组。

    当您处理此类“深层”结构时,您将需要某种形式的迭代来更新它们。

    For 循环是一个很好的起点,但它们通常会导致java.util.ConcurrentModificationExceptions。所以更容易处理数据的临时副本,然后在迭代完成后替换相应的_source 属性:

    {
      "query": {
        "match_all": {}
      },
      "script": {
        "source": """
          if (ctx._source.tagtypes == null) { return; }
          
          def originalTagtypes = ctx._source.tagtypes;
          def newTagtypes = [];
          
          for (outerGroup in originalTagtypes) {
            // keep what we've got
            newTagtypes.addAll(outerGroup);
            
            // group already present?
            def atLeastOneGroupContainsTag = outerGroup.stream().anyMatch(tagGroup -> tagGroup.containsKey(params.tag));
            
            // if not, add it as a hashmap of one single empty list
            if (!atLeastOneGroupContainsTag) {
              Map m = new HashMap();
              m.put(params.tag, []);
              newTagtypes.add(m);
            } 
          }
          
          ctx._source.tagtypes = [newTagtypes];
        """,
        "lang": "painless",
        "params": {
          "tag": "CPU"
        }
      }
    }
    

    最终会像这样更新tagtypes

    {
     ...
      "tagtypes" : [
        [
          {
            "Memory" : [ ]
          },
          {
            "CPU" : [ ]        <---
          }
        ]
      ],
      ...
    }
    

    当您说文档示例太基础时,您是对的。无耻的插头:我最近published a handbook 旨在解决这个问题。您会发现许多重要的脚本示例,以更好地理解 Painless 脚本语言。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-08-02
      • 1970-01-01
      • 2012-01-03
      • 2020-05-21
      • 1970-01-01
      • 2018-08-01
      • 2021-08-03
      • 1970-01-01
      相关资源
      最近更新 更多