c# - 在一次调用中接收按文档类型分组的搜索结果(NEST、AWS Elasticsearch)
问题描述
全部。在此先感谢您的帮助!
我正在使用 NEST 从 AWS Elasticsearch 请求分页数据。AWS Elasticsearch 索引中的每个文档都有一个内容类型(主题、问题和视频)。作为回应,我收到了当前页面的文档列表及其总结果。一切都很好。
所以问题是:我怎样才能在一个电话中收到某种响应地图以及搜索结果?
我的意思是,例如,这是我的回复:
文档 1 - 主题
文档 2 - 主题
文档 3 - 视频
文档 4 - 问题
文档 5 - 视频
总结果:5 项。
除此之外,我希望收到以下“地图”:
主题 - 2 项
视频 - 2 项
问题 - 1 项
是否可以在一个请求中完成?或者如何通过几个请求来完成?也许 NEST Aggregations 是需要的解决方案,但似乎没有“计数”逻辑
这是分页数据和一些模型的搜索请求:
public class Document
{
public int DocumentId { get; set; }
public ContentType ContentType { get; set; }
public DateTime UpdatedOn { get; set; }
public string Title { get; set; }
public string Description { get; set; }
}
public virtual DocumentSearchResponse FullTextSearch(DocumentSearchParams searchParams)
{
var resultsSearchRequest = _elasticClient.Search<Document>(s => s.Index("some_index")
.Query(q => q.Term(t => t.Field(f => f.DocumentId).Value(searchParams.ContentId))
&& q.Terms(t => t.Field(f => f.ContentType).Terms(searchParams.GetContentTypesIds()))
&& q.MultiMatch(m => m.Fields(fs => fs.Field(f => f.Title).Field(f => f.Description))
.Query(searchParams.SearchValue)
.Type(TextQueryType.MostFields)))
.Sort(ss => ss.Descending(f => f.UpdatedOn))
.From((searchParams.PageNumber - 1) * searchParams.PageSize)
.Size(searchParams.PageSize));
// Is valid check
return new DocumentSearchResponse
{
PageResults = _searchResponseHelper.ToPageResults(resultsSearchRequest.Documents),
PageResultsMap = new Dictionary<ContentType, int>, // <- here
TotalResultsCount = resultsSearchRequest.HitsMetadata.Total.Value
};
}
解决方案
所以,我发现了。也许,有人会发现它有帮助。我需要的是“聚合”。在 .Form 和 .Size 之前添加以下行将按指定字段对搜索结果进行分组:
.Aggregations(a => a.Terms("contentType", t => t.Field(f => f.ContentType)))
.Query(...)
.Form(...)
.Size(...)
要将结果处理到我需要的 Dictionary 中,请添加以下内容(
searchAggregations
is searchResponse.Aggregations
):
public Dictionary<ContentType, long> ToPageResultsMap(AggregateDictionary searchAggregations)
{
var pageResultsMap = new Dictionary<ContentType, long>();
var buckets = searchAggregations.Terms(DataConsts.SearchContentTypeDocFieldName).Buckets;
foreach (var item in buckets)
{
if(int.TryParse(item.Key, out int contentType))
{
pageResultsMap.Add((ContentType)contentType, item.DocCount.HasValue ? item.DocCount.Value : 0);
}
}
return pageResultsMap;
}
推荐阅读
- angular - Angular 5 - 强制用户获取新版本的应用程序
- javascript - 当存在特定的屏幕宽度和类别时执行某些操作
- php - PHP:做我自己的缓冲与使用“ob_ *”函数
- c# - Unity中Sprite上的滚动纹理以获得背景滚动效果,不起作用
- c++ - QAction::text(),程序收到信号 SIGSEGV,分段错误
- sqlite - 承诺返回所有列值 sqlite ionic sqlite swift
- tensorflow - 在小批量的多 GPU 上进行训练
- python - 在 Raspberry Pi 上运行 TensorFlow 模型推理的首选方法是什么?
- erlang - 在处理状态超时时优雅地退出 gen_statem
- azure-devops - 是否可以只允许利益相关者访问特定的董事会?