首页 > 解决方案 > 在一次调用中接收按文档类型分组的搜索结果(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
    };
}

标签: c#amazon-web-serviceselasticsearchnestaws-elasticsearch

解决方案


所以,我发现了。也许,有人会发现它有帮助。我需要的是“聚合”。在 .Form 和 .Size 之前添加以下行将按指定字段对搜索结果进行分组:

.Aggregations(a => a.Terms("contentType", t => t.Field(f => f.ContentType)))
.Query(...)
.Form(...)
.Size(...)

要将结果处理到我需要的 Dictionary 中,请添加以下内容( searchAggregationsis 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;
}

推荐阅读