由ElasticSearch聚合驱动的下拉列表

mutmk8jj  于 2022-12-22  发布在  ElasticSearch
关注(0)|答案(1)|浏览(128)

目前在搜索组件中使用的下拉列表是由ES使用术语聚合驱动的。下拉列表在选中时应该过滤其他下拉列表,但不会进一步过滤自身。我目前基本上正在进行两次搜索来完成这一点,并从两次搜索中收集聚合。第一次是大小为0,给定的查询不包括最近应用的过滤器:
(为岗位简化)

// for aggregation on last filter selected
var newestFilterResponse = await _client.SearchAsync<Index>(s => s
           .Index(_index)
           .From(0)
           .Size(0)
           .Query(QueryClosure(phrase, fields, filtersMinusLast))
           .Aggregations(FilterOptionsAggregationClosure(lastFilter)));

 // actual query for results and aggregation on other filters
var response = await _client.SearchAsync<Index>(s => s
            .Index(_index)
            .From(0)
            .Size(500)
            .Query(QueryClosure(phrase, fields, allFilters))
            .Aggregations(FilterOptionsAggregationClosure(allFiltersExceptLast)));

使用下面为每个下拉列表构建术语聚合

Func<AggregationContainerDescriptor<Index>, IAggregationContainer> FilterOptionsAggregationClosure(List<FilterButton> filterButtons)
    {

        return delegate (AggregationContainerDescriptor<Index> aggregationContainerDescriptor)
        {
            foreach (var filterButton in filterButtons)
            {
                aggregationContainerDescriptor = aggregationContainerDescriptor
                    .Terms(filterButton.AggregationName, t => t
                        .Field(filterButton.FieldToSearch)
                        .Size(10000)
                    );
            }

            return aggregationContainerDescriptor;
        };
}

使用下面的代码来构建查询(例如,简化为仅筛选,但在我的实际用例中有多匹配、前缀等)

Func<QueryContainerDescriptor<Index>, QueryContainer> QueryClosure(string phrase, Fields fields, List<FilterApplied> filtersApplied)
    {

        return delegate (QueryContainerDescriptor<Index> queryContainerDescriptor)
        {
            // multimatch, prefix, etc. on phrase for fields supplied
            QueryContainer queryContainer = GetKeywordQuery(phrase, fields);

            QueryContainer filterQuery = new();
            foreach (var filter in filtersApplied)
            {
                QueryContainer sameFilterQuery = new QueryContainerDescriptor<Index>()
                    .Bool(boolQuery => boolQuery
                        .Filter(f => f
                            .Terms(terms => terms
                                .Field(filter.FieldToSearch)
                                .Terms(filter.Values))));

                filterQuery = filterQuery && sameFilterQuery;

            }

            return queryContainer && filterQuery;

        };

    }

我觉得这不是办法。任何改进的建议都将不胜感激。谢谢!

dnph8jn4

dnph8jn41#

最终在会话存储中缓存下拉选项,我们希望url参数能够在共享链接时生成准确的页面状态,但最终放弃了过滤器下拉状态,这样我们就可以消除对最后应用的过滤器类型进行隔离聚合的需要

相关问题