根据重复的嵌套类型获取重复的文档

时间:2019-04-26 10:01:20

标签: java elasticsearch

大家好。 我的文档类型为“ generalTask​​”,其中包含一组嵌套文档,称为“ completeUser”。

这里是映射:

{
    "generalTask": {
        "properties": {
            "id": {
                "type": "long"
            },
            "completeUser": {
                "type": "nested",
                "properties": {
                    "completeTime": {
                        "type": "long"
                    },
                    "userId": {
                        "type": "long"
                    }
                }
            }
        }
    }
}

现在,我们有两个文档。

例如

{
    "_source": {
        "id": 1001,
        "completeUser": [
            {
                "userId": 1,
                "completeTime": 100
            },
            {
                "userId": 1,
                "completeTime": 300
            },
            {
                "userId":1,
                "completeTime": 500
            }
        ]
    }
}

{
    "_source": {
        "id": 1002,
        "completeUser": [
            {
                "userId": 1,
                "completeTime": 200
            },
            {
                "userId": 1,
                "completeTime": 400
            },
            {
                "userId":1,
                "completeTime": 600
            }
        ]
    }
}

我可以像这样通过嵌套聚合获取docCount(为6):

    BoolQueryBuilder query = QueryBuilders.boolQuery();
    query.must(nestedQuery("completeUser", termQuery("completeUser.userId", 1)));   
     BoolQueryBuilder builder = getClient().prepareSearch(getIndexName()).setTypes(getIndexType()).setQuery(query)
                        .addAggregation(AggregationBuilders.nested("nested").path("completeUser")
                                .subAggregation(AggregationBuilders.count("count").field("completeUser.userId"))).setSize(0);
   SearchResponse searchResponse = getSearchResponse(builder);
   Nested nested = searchResponse.getAggregations().get("nested");
    long docCount = nested.getDocCount();  // the docCount is 6

,但searchResponse中仍然只有2个文档:

SearchRequestBuilder builder = getClient().prepareSearch(getIndexName()).setTypes(getIndexType())
                .setSearchType(SearchType.QUERY_THEN_FETCH).setQuery(query).setFrom(0).setSize(5); // the size is 5
builder.addSort(SortBuilders.fieldSort("completeUser.completeTime")
                    .setNestedFilter(FilterBuilders.termFilter("completeUser.userId", 1))
                    .order(SortOrder.DESC));
SearchResponse searchResponse = getSearchResponse(builder);

但是我想要的是基于completeTime的重复文档。

如何在completeTime之前按searchResponse顺序获得5个(大小值)文档?

哦,是的。 ElasticSearch版本是1.4.5

1 个答案:

答案 0 :(得分:0)

由于索引中只存储了两个文档(或者至少有两个与您的查询匹配的文档),所以这两个文档将在SearchResponse中返回给您。您无法直接获取按completeTime排序的前五个嵌套文档,因为搜索响应包含存储在索引中的整个对象。

您的解决方案是用Java代码解析结果:

  • 由于您将查询大小设置为5,因此最多返回五个结果,首先按最高completeTime排序。这意味着您确实会收到所有必需的数据,然后再接收更多
  • 使用Java解析所有嵌套文档,然后再次对它们进行排序,并获取其中的前五个