使用java高级rest客户端将Id列表作为Multi-Get请求的参数传递

时间:2021-02-10 15:16:13

标签: java elasticsearch elasticsearch-rest-client

我正在尝试使用 java 高级 rest-client 获取索引中存在的所有文档的列表。

样本索引数据为-

PUT /my-index/_doc/1
{
  "account_number": 1,
  "balance": 28838
}

PUT /my-index/_doc/2
{
  "account_number": 1,
  "balance": 28838
}

PUT /my-index/_doc/3
{
  "account_number": 1,
  "balance": 28838
}

要通过ID检索多个JSON文档,我使用了multi-get API,如下图

GET /_mget
{
  "ids": [
    "2",
    "3",
    "4"
  ]
}

搜索结果是

{
  "docs": [
    {
      "_index": "my-index",
      "_type": "_doc",
      "_id": "2",
      "_version": 1,
      "_seq_no": 4,
      "_primary_term": 4,
      "found": true,
      "_source": {
        "account_number": 2,
        "balance": 28838
      }
    },
    {
      "_index": "my-index",
      "_type": "_doc",
      "_id": "3",
      "_version": 2,
      "_seq_no": 5,
      "_primary_term": 4,
      "found": true,
      "_source": {
        "account_number": 3,
        "balance": 28838
      }
    },
    {
      "_index": "my-index",
      "_type": "_doc",
      "_id": "4",
      "found": false
    }
  ]
}

现在,我需要解析多获取请求生成的响应,并获取在索引中找到的所有 id 的列表。

Java 代码

我能够获得 Id 列表,即 [2,3](这是预期的结果)。但如下面的 java 代码所示,我每次都使用 ids 循环从 for 列表中添加一个元素(文档 ID)。因此,每次创建新的多获取请求时。

public List<Integer> verifyDocuments(final VerifyScrollRequest request) throws IOException {
        RestHighLevelClient es7Client = buildES7Client(request.getEs7Node(), request.getEs7Port());
        List<String> ids = new ArrayList<>();
        ids.add("2");
        ids.add("3");
        ids.add("4");
        List<Integer> documents = new ArrayList<>();
        MultiGetRequest getRequest = new MultiGetRequest();
        for (int i = 0; i < ids.size(); i++) {
            String element = ids.get(i);
            getRequest.add(new MultiGetRequest.Item(request.getEs7IndexName(), element));
            MultiGetResponse response = es7Client.mget(getRequest, RequestOptions.DEFAULT);
            if (response.getResponses()[i].getResponse().isExists()) {
                documents.add(Integer.parseInt(element));
            }
        }
        return documents;
    }

有什么办法可以把Id的完整列表作为参数传递给multi-get请求,这样multi-get请求只创建一次?

1 个答案:

答案 0 :(得分:1)

您不需要在每次迭代时发送调用 es7Client.mget()。这就是我的做法:

    public List<Integer> verifyDocuments(final VerifyScrollRequest request) throws IOException {
        RestHighLevelClient es7Client = buildES7Client(request.getEs7Node(), request.getEs7Port());
        // build the list of IDs
        List<String> ids = new ArrayList<>();
        ids.add("2");
        ids.add("3");
        ids.add("4");
        List<Integer> documents = new ArrayList<>();

        // build the mget request with all IDs
        MultiGetRequest getRequest = new MultiGetRequest();
        for (int i = 0; i < ids.size(); i++) {
            String element = ids.get(i);
            getRequest.add(new MultiGetRequest.Item(request.getEs7IndexName(), element));
        }

        // call mget
        MultiGetResponse response = es7Client.mget(getRequest, RequestOptions.DEFAULT);

        // iterate over the resulting documents
        for (int i = 0; i < ids.size(); i++) {
            if (response.getResponses()[i].getResponse().isExists()) {
                documents.add(Integer.parseInt(element));
            }
        }

        return documents;
    }