在同一行业的公司中,我需要列出收入最高的前5家公司,以及哪家公司在该行业中排名。编写第一个查询很容易:
GET myIndex/_search
{
"from": 0,
"size": 5,
"query": {
"match": {
"industryCode": "xxxx"
}
},
"sort": [
{
"revenue": {
"order": "desc"
}
}
]
}
但我不知道如何编写第二个查询。目前,我必须使用滚动功能来扫描同行业公司的所有记录,如下所示:
async Task<int> GetRank()
{
int rank = 0;
searchRequest.Size = 500;
searchRequest.From = 0;
searchRequest.Scroll = "1m";
var rs = await _elasticClient.SearchAsync<Tmp>(searchRequest);
while (rs.Documents.Count > 0)
{
foreach (var item in rs.Documents)
{
rank++;
if (item.OrganCode == request.OrganCode) return rank;
}
rs = _elasticClient.Scroll<Tmp>("1m", rs.ScrollId);
}
return rank;
}
这种方法确实非常缓慢,如果公司的收入非常低,可能需要几分钟才能产生结果。有什么办法解决这个问题吗?非常感谢!!!
如果我正确理解你的问题,你想得到收入最高的前5家公司,按行业代码分组。这可以通过terms
聚合和top_hits
子聚合来实现
{
"aggs": {
"industry_codes": {
"aggs": {
"top_companies": {
"top_hits": {
"size": 5,
"sort": [
{
"revenue": {
"order": "desc"
}
}
]
}
}
},
"terms": {
"field": "industryCode"
}
}
},
"size": 0
}
在NEST中,这看起来像
var client = new ElasticClient(settings);
var searchResponse = client.Search<Tmp>(s => s
.Size(0)
.Aggregations(a => a
.Terms("industry_codes", t => t
.Field(f => f.IndustryCode)
.Aggregations(aa => aa
.TopHits("top_companies", th => th
.Sort(so => so
.Descending(f => f.Revenue)
)
.Size(5)
)
)
)
)
);
获得每个行业代码的热门
var termsAgg = searchResponse.Aggregations.Terms("industry_codes");
foreach (var bucket in termsAgg.Buckets)
{
var topHits = bucket.TopHits("top_companies");
foreach (var company in topHits.Documents<Tmp>())
{
// do something with company
}
}