工作Lucene SearchAfter示例

时间:2014-06-05 10:22:24

标签: java lucene

我正在尝试使用Lucene 4.8.1的SearchAfter方法在Web应用程序中实现搜索结果的分页。

以前曾经问过类似的问题,但那里接受的答案对我不起作用:

Stack Overflow Question: Lucene web paging

当我以这种方式从头开始创建Lucene ScoreDoc以用作SearchAfter的参数时:

   ScoreDoc sd = new ScoreDoc(14526, 0.0f);
   TopDocs td = indexSearcher.searchAfter(sd, query, null, PAGEHITS);

我得到了这个例外:

java.lang.IllegalArgumentException: after must be a FieldDoc

这似乎与文档相反。但无论如何,当我创建一个Field Doc时,我得到:

java.lang.IllegalArgumentException: after.fields wasn't set

after.fields是一个Object数组,所以我很难用我在URI中传递的信息来设置它!

我找不到任何使用SearchAfter的工作代码示例。我的原始计划显然是创建一个新的ScoreDoc,如前一个问题所示。任何人都可以建议我可能做错了什么,或链接到SearchAfter的任何工作代码示例?

谢谢!

2 个答案:

答案 0 :(得分:1)

我不相信你可以创建一个scoredoc,然后将其传递给searchAfter。您需要使用先前搜索返回的ScoreDocs。

答案 1 :(得分:0)

可以尝试一下。

@Test
public void searchAfter() {
    Object[] objects = new Object[]{"1"};
    List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
    boolean type = true;
    while (type) {
        SearchHits searchHits = searchAfter(objects);
        SearchHit[] hits = searchHits.getHits();
        if (hits != null && hits.length > 0){
            objects = hits[hits.length-1].getSortValues();
            if (hits.length < size) type = false;
            for (SearchHit hit : hits) {
                data.add(hit.getSourceAsMap());
                System.out.println(JsonUtil.objectToJson(hit.getSourceAsMap()));
            }
        }

    }
    Iterator<Map<String, Object>> iterator = data.iterator();
    while (iterator.hasNext()) {
        System.out.println(iterator.next().toString());
    }
    System.out.println(data.size() + "-----------------");

}

public SearchHits searchAfter(Object[] objects) {
    SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
    sourceBuilder.query(QueryBuilders.termQuery("age", "33"));
    sourceBuilder.size(size);
    sourceBuilder.sort("account_number", SortOrder.ASC);
    sourceBuilder.searchAfter(objects);

    SearchRequest searchRequest = new SearchRequest();
    searchRequest.indices("bank");
    searchRequest.source(sourceBuilder);
    ActionFuture<SearchResponse> response = elasticsearchTemplate.getClient().search(searchRequest);

    SearchHits searchHits = response.actionGet().getHits();
    return searchHits;
}