【问题标题】:ElasticSearch updating documents in an automated wayElasticSearch 以自动方式更新文档
【发布时间】:2020-03-21 21:23:28
【问题描述】:

我不知道如何就我当前的问题提出问题,所以我想,这就是我找不到正确答案的原因。所以请让我告诉你我的问题是什么。

我正在尝试使用 Zmap 和 Zgrab (如 Shodan.io、censys.io 等)来做一个简单的互联网端口扫描器。

我需要将数据存储在 ElasticSearch 中(因为我想学习如何使用它)。

在这种情况下;

我创建了一个 JSON 架构以在 ElasticSearch 中使用它,例如

{
    "value": "192.168.0.1",
    "port": [
      {
        "value": 80,
        "HTMLbody": "BODY OF THE WEB PAGE",
        "status": 200,
        "headers": {
          "content_type": "html/png",
          "content_length": 23123,
          "...": "..."
        },
        "certificate": {
          "company_names": [
            "example.com",
            "acme.io"
          ]
        }
      }
    ]
}

Elasticsearch 内部将有大约 40 亿个 IP 地址,并打开不同的端口。我的问题从这里开始;第一次初始扫描后,我需要更新现有的 IP 地址。

例如;

IP:192.168.0.1 端口:80开放

在第二次扫描时,我扫描端口 443,它也可能是开放的。然后我需要根据打开的端口更新我的 Elasticsearch 文档。

到目前为止我发现了什么

我找到了一个端点,它是; POST /<index>/_update/<_id> 但它会更新单个文档。我需要在一次扫描中更新至少超过 100.000 个文档。它也应该是自动的。我怎么知道一个 ip 地址文件 id 并更新它?

其次,我发现了;

POST <index>/_update_by_query

我考虑过使用查询搜索IP地址并收集其索引号,然后更新文档如下;


{

    "value": "192.168.0.1",
    "port": [
      {
        "value": 80,
        "HTMLbody": "BODY OF THE WEB PAGE",
        "status": 200,
        "headers": {
          "content_type": "html/png",
          "content_length": 23123,
          "...": "..."
        },
        "certificate": {
          "company_names": [
            "example.com",
            "acme.io"
          ]
        }
      },

      {
        "value": 443,
        "HTMLbody": "BODY OF THE SSL WEB PAGE",
        "status": 200
      }
    ]
}

理论上,我可以做到这一点,但在实践中无法编写高效的代码。因为我有至少 6 GB 的 JSON 文件进行一次扫描,并且处理整个文件和更新 elasticsearch 需要很长时间。

有没有什么方法可以有效解决这个问题?

Please Look the image below

【问题讨论】:

  • 你试试Bulk API 吗?您可以添加多个查询,例如更新或索引,并且在代码中使用起来很简单。您只需要正确构建要更新的文档并确保映射正确。您使用哪种语言来执行此操作?
  • 我正在使用 Python。我看到了 Bulk API,但我不知道每个 IP 地址的确切索引 ID,那么如何使用 Bulk API 更新它?我对 ElasticSearch 非常陌生,也许我不了解 Bulk API 的逻辑
  • 你能看看我帖子底部的图片吗?这正是我需要的,但我不知道索引 ID 在 Elasticsearch 内部的排列。在这种情况下,如何在不知道其 ID 号的情况下更新正确的文档?
  • 如果我理解,每个文档代表一个 IP 地址,并且您想在一个新端口为一个 IP 地址启用时更新文档?为什么不使用 ip 地址作为 _id ?这样,您可以轻松定义要更新的文档并构建更新查询。对于bulk部分,假设是一个数组,你在这个数组中添加一些查询,最后,你执行所有这些查询数组,bulk api会高效地完成。
  • 哇,我什至没有想过使用ip地址作为_id。这对你来说可能是个小主意,但会对我有很大帮助,非常感谢!我的最后一个问题是;据我所知,Elasticsearch 文档是不可变的。这意味着它删除现有文档并使用更新的部分创建新文档。在这种情况下;我需要知道 json 文件的确切状态吗?如何在现有信息下方添加信息?例如帖子顶部的 Json 文件。如何使用批量 api 向其添加 443 端口?我害怕覆盖现有数据。

标签: python json elasticsearch


【解决方案1】:

要完整回答问题,首先,使用ip地址为_id,使sur更新相应的文档。 您需要在端口数组中添加一个条目,因此请使用_update API 来执行它:

POST <index>/_update/192.168.0.1
{
  "script": {
    "source": "ctx._source.port.add(params.tag)",
    "lang": "painless",
    "params": {
      "tag": {
        "value": 443,
        "HTMLbody": "BODY OF THE SSL WEB PAGE",
        "status": 200
      }
    }
  }
}

这是一个update query,用一个小脚本向数组添加一个条目。

要使用批量,只需按照here 的说明添加您的所有请求

【讨论】:

  • 谢谢,但现在我遇到了一些不同的问题。这是我可以更新值的方式。但我需要在 Port[] 数组中添加 JSON 对象。我进行了一些搜索,但找不到有关通过添加新对象来更新字段的答案。
  • tag 上的值是一个 jsonobject,它应该按预期使用。我的答案包括您作为示例提供的 json,但我犯了一个错误,在 source 指令中,我已经编辑了我的答案以使其工作!
  • 它就像魔术一样工作。你是我“本月英雄”名单的第一名!
猜你喜欢
  • 1970-01-01
  • 2016-01-18
  • 2018-01-31
  • 2019-10-13
  • 1970-01-01
  • 1970-01-01
  • 2015-07-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多