c# - Elasticsearch:获取特定商品的订购号
问题描述
在同行业的公司中,我需要选择收入最高的前 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
}
}
推荐阅读
- elasticsearch - 日期直方图聚合 Elasticsearch
- sql - 有没有办法从 SQL 中的主查询内容中动态选择子查询中的表?
- symfony - api平台,无法使用symfony 4向抽象类添加自定义搜索过滤器
- c# - 我们可以在不创建自定义控件的情况下拦截多个 TextBox 的 KeyPress 事件吗?
- shopify - 如何根据客户标签显示自定义“登录”欢迎消息?(Shopify/液体)
- google-cloud-platform - gcloud beta ai - PERMISSION_DENIED
- vba - 使用可见性属性后,组合框被禁用
- react-native - 样式化的组件是 React Native 的坏习惯?
- angular - Angular 10 - 将 FormControl 数组值转换为用逗号分隔的字符串
- r - 当我使用 xts 包将数据框转换为时间序列数据时,数字和整数变量在 R 中被更改为字符变量