【问题标题】:How to create a HashMap with custom object as a key?如何创建以自定义对象为键的 HashMap?
【发布时间】:2020-06-18 14:27:06
【问题描述】:

在 Elasticsearch 中,我有一个包含对象数组的对象。数组中的每个对象都有typeidupdateTimevalue 字段。

我的输入参数是一个数组,其中包含相同类型但值和更新时间不同的对象。我想在它们存在时用新值更新对象,并在它们不存在时创建新值。

我想使用 Painless 脚本来更新它们,但要保持它们不同,因为其中一些可能重叠。问题是我需要同时使用typeid 来保持它们的唯一性。到目前为止,我已经使用蛮力方法完成了它,嵌套了 for 循环并比较了两个数组的元素,但我对此不太满意。

其中一个想法是从源中获取数组,构建临时 HashMap 以进行快速查找,处理输入,然后将所有对象存储回源中。

我可以使用自定义对象(具有typeid 的类)作为键创建 HashMap 吗?如果是这样,该怎么做?我无法将类定义添加到脚本中。

这是映射。所有字段都“禁用”,因为我仅将它们用作中间状态并使用其他字段进行查询。

{
  "properties": {
    "arrayOfObjects": {
      "properties": {
        "typ": {
          "enabled": false
        },
        "id": {
          "enabled": false
        },
        "value": {
          "enabled": false
        },
        "updated": {
          "enabled": false
        }
      }
    }
  }
}

示例文档。

{
  "arrayOfObjects": [
    {
      "typ": "a",
      "id": "1",
      "updated": "2020-01-02T10:10:10Z",
      "value": "yes"
    },
    {
      "typ": "a",
      "id": "2",
      "updated": "2020-01-02T11:11:11Z",
      "value": "no"
    },
    {
      "typ": "b",
      "id": "1",
      "updated": "2020-01-02T11:11:11Z"
    }
  ]
}

最后是当前形式的脚本的一部分。脚本还做了一些其他的事情,所以为了简洁起见,我把它们删掉了。

if (ctx._source.arrayOfObjects == null) {
    ctx._source.arrayOfObjects = new ArrayList();
}
for (obj in params.inputObjects) {
    def found = false;
    for (existingObj in ctx._source.arrayOfObjects) {
        if (obj.typ == existingObj.typ && obj.id == existingObj.id && isAfter(obj.updated, existingObj.updated)) {
            existingObj.updated = obj.updated;
            existingObj.value = obj.value;
            found = true;
            break;
        }
    }
    if (!found) {
        ctx._source.arrayOfObjects.add([
            "typ": obj.typ,
            "id": obj.id,
            "value": params.inputValue,
            "updated": obj.updated
        ]);
    }
}

【问题讨论】:

  • 你的脚本现在是什么样子的?你也可以分享一些文档吗?映射的相关部分也会很好。
  • @joe 完成。希望这就足够了。如果需要,我很乐意添加更多内容。
  • 谢谢,有帮助。

标签: elasticsearch hashmap elasticsearch-painless


【解决方案1】:

从技术上讲,您的方法没有任何不理想的地方。

HashMap 可能会节省一些时间,但由于您正在编写脚本,因此您已经被其固有的低效率所束缚...顺便说一句 here's how 您初始化并使用 HashMaps。

另一种方法是重新考虑您的数据结构——而不是使用键控对象或类似的对象数组。对象数组不适合频繁更新。

最后提示:您说这些字段仅用于存储一些中间状态。如果不是这种情况(或者将来不会),我建议使用nested 数组来启用独立于array 中其他对象的查询。

【讨论】:

  • 感谢您的回答,我可能会留在那里。在 ES 中创建动态键有它自己的问题,我喜欢这种数据结构的简单性。关于文档,寿 - 我知道他们,只是我不知道如何创建多值键。文档那里只有现有的类型。主要问题是如何创建具有多个值的键(此处为 type 和 id)?从技术上讲,我可以将它们连接起来,但我认为拥有对象会更优雅。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 1970-01-01
  • 2011-11-08
  • 1970-01-01
  • 2011-07-09
  • 1970-01-01
相关资源
最近更新 更多