我正在使用带有Java API的elasticsearch来使用滚动方法获取数据,因为我有很多数据,我试图通过scrollId使用多个和后续请求对数据进行分页。
示例:
而不是:
POST http://localhost:8080/country
返回:
[
{
scrollId: abc,
data: [{country: brazil}, {country: argentina}]
},
{
scrollId: def,
data: [{country: france}, {country: germany}]
}
]
我想用:
POST http://localhost:8080/country?paged=true
响应中的第一个scrollId:
{
nextScrollId: abc
}
然后我可以在nextScrollId
存在时执行一些请求:
POST http://localhost:8080/country?scrollId=abc
返回:
{
nextScrollId: def,
data: [{country: brazil}, {country: argentina}] //data from the "abc" scrollId
}
然后:
POST http://.../data?scrollId=def
返回:
{
nextScrollId: "", //no more results in this case
data: [{country: france}, {country: germany}] //data from the "def" scrollId
}
目前我正在使用这段代码:
SearchResponse scrollResponse = elastic.getDataFromElasticSearch();
boolean hasNext = true;
String scrollId = request.getScrollId();
CountryResponse countryResponse = new CountryResponse();
do {
if (scrollResponse.getScrollId().equals(scrollId)) {
scrollResponse = client.prepareSearchScroll(scrollId)
.setScroll(TimeValue.timeValueMinutes(1))
.execute()
.actionGet();
//here i get the data from scrollResponse.getHits().getHits()
//and format it to that nextScrollId | data structure
countryResponse.addCountriesFromElasticSearchResponse(scrollResponse);
} else {
hasNext = false;
}
} while (hasNext == true);
countryResponse.setNextScrollId(scrollResponse.getScrollId());
return countryResponse;
有了这个,我可以正确地返回下一个scrollId。
这里的事情是,每当我尝试使用nextScrollId准备滚动数据时,我在响应中没有数据。
这可能吗?
答案 0 :(得分:0)
滚动API旨在以单向方式由单个线程使用。 在内部,它创建一个光标,只能通过搜索结果向前移动,每次调用都会改变光标状态,并且不可能为同一个光标重复相同的调用两次(滚动)。
在你的情况下,问题在于理解滚动如何在内部工作 - 第一页只能通过第一次调用获得:
为了实现带有移位迭代器的自定义逻辑(如下所述)
您必须在第一次请求时缓存搜索结果,并使用"您自己的迭代器"将它们保存(缓存)在您的服务器上转移到原始的弹性迭代器。还要记住:
所以我强烈建议您按照文档中描述的方式使用elastic scroll API。