elasticsearch:获取特定项目的订单号

j8yoct9x  于 2021-06-13  发布在  ElasticSearch
关注(0)|答案(1)|浏览(299)

在同一行业的公司中,我需要选择收入最高的前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;
}

这种方法确实非常慢,如果公司的收入非常低,可能需要几分钟才能产生结果。有办法解决这个问题吗?非常感谢你!!!

l2osamch

l2osamch1#

如果我对你的问题理解正确的话,你想得到收入最高的前5家公司,按行业代码分组。这可以通过 terms 聚合和a top_hits 子聚合

{
  "aggs": {
    "industry_codes": {
      "aggs": {
        "top_companies": {
          "top_hits": {
            "size": 5,
            "sort": [
              {
                "revenue": {
                  "order": "desc"
                }
              }
            ]
          }
        }
      },
      "terms": {
        "field": "industryCode"
      }
    }
  },
  "size": 0
}

在巢穴里,这看起来像

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        
    }
}

相关问题