使用SORT BY的Redis FTAggregate不适用于游标

7eumitmz  于 2023-10-15  发布在  Redis
关注(0)|答案(1)|浏览(139)

我尝试在Java中使用FTAggregate批量处理一些数据。如果我使用sortBy,我只在ft.aggregate调用上得到结果,而在后续的游标读取上没有结果。我的排序字段被索引为NUMERIC和SORTABLE。是我做错了什么,还是我想要的行为?因为我在Redis文档中找不到任何关于CURSOR和SORT BY交互的信息。如果我删除sortBy(),一切都正常。如果我只使用sortBy()而不使用limit(),我只得到10个结果,没有后续的结果,因为如果没有指定,sort by的默认限制是10。所以我的问题是,sortBy可以和CURSOR一起工作吗?或者我应该使用LIMIT和offset来分页,即使这意味着性能下降?

public void fetchData() {
   var chuckSize = 1000;
   var result = jedis.ftAggregate("myIndex", new AggregationBuilder("*")
                     .loadAll()
                     .sortBy("myField")
                     .limit(chuckSize)
                     .cursor(chuckSize, 1000));
   var cursor = new AtomicLong(result.getCursorId());
   while(true) {
       try {
         //process result
         result = jedis.ftCursorRead("myIndex",cursor.get(), chunckSize);
         cursor.set(result.getCursorId());
       } catch(JedisDataException e) {
         //data read end
         break;
       }
}
rslzwgfq

rslzwgfq1#

在我看来,您只是在第一次迭代时耗尽了查询。
尝试给光标一个较小的读取计数。默认的排序限制是10,可以更大,但它表示查询将产生的结果总数
游标应该在每次读取时给予结果的数量,如果您将查询限制为结果的数量,则将在第一次调用时获得所有结果。
Jedis代码:

public AggregationBuilder cursor(int count) {
    isWithCursor = true;
    aggrArgs.add(SearchKeyword.WITHCURSOR);
    aggrArgs.add(SearchKeyword.COUNT);
    aggrArgs.add(count);
    return this;
  }

  public AggregationBuilder cursor(int count, long maxIdle) {
    isWithCursor = true;
    aggrArgs.add(SearchKeyword.WITHCURSOR);
    aggrArgs.add(SearchKeyword.COUNT);
    aggrArgs.add(count);
    aggrArgs.add(SearchKeyword.MAXIDLE);
    aggrArgs.add(maxIdle);
    return this;
  }

看起来光标要么获得块大小,要么获得块大小和外派限制(就像redis中的其他键一样)。
您需要定义查询限制。试试这样的方法:

public void fetchData() {
   var chuckSize = 1000;
   var queryLimit = chunkSize * 10;
   var result = jedis.ftAggregate("myIndex", new AggregationBuilder("*")
                     .loadAll()
                     .sortBy("myField")
                     .limit(queryLimit)
                     .cursor(chuckSize));
   var cursor = new AtomicLong(result.getCursorId());
   while(true) {
       try {
         //process result
         result = jedis.ftCursorRead("myIndex",cursor.get(), chunckSize);
         cursor.set(result.getCursorId());
       } catch(JedisDataException e) {
         //data read end
         break;
       }
}

相关问题