public IEnumerable <string> SearchProducts(IEnumerable <object> filters, string categoryId)
        {
            FilterContainer filterContainer =
                new FilterDescriptor <ProductIndex>().Term(t => t.CategoryId, categoryId) &&
                BuildParamsFilter(filters);

            var searchRequest = new SearchRequest
            {
                Size         = 0,
                Aggregations = new Dictionary <string, IAggregationContainer>
                {
                    {
                        "agg", new AggregationContainer
                        {
                            Filter = new FilterAggregator
                            {
                                Filter = filterContainer
                            },
                            Aggregations = new Dictionary <string, IAggregationContainer>
                            {
                                {
                                    "productId", new AggregationContainer
                                    {
                                        Terms = new TermsAggregator
                                        {
                                            Size  = 0,
                                            Field = Property.Path <ProductIndex>(p => p.Id)
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };

            ISearchResponse <ProductIndex> result = _client.Search <ProductIndex>(searchRequest);

            SingleBucket filterAgg = result.Aggs.Filter("agg");

            if (filterAgg != null)
            {
                IEnumerable <string> productIds =
                    filterAgg.Terms("productId").Items
                    .Select(item => item.Key)
                    .ToList();
                return(productIds);
            }
            return(Enumerable.Empty <string>());
        }
        private IList <RequestBucketComposite> BuildAttributeTree(SingleBucket nestedBucket, IList <RequestBucketComposite> selected)
        {
            var typesBucket = nestedBucket.Terms("attribute_agg");
            var result      = new List <RequestBucketComposite>();

            if (selected == null)
            {
                return(result);
            }

            foreach (var type in typesBucket.Items)
            {
                var selectedType = selected.Where(x => string.Compare(x.Key, type.Key, true) == 0);

                var typeEntity = new RequestBucketComposite();
                typeEntity.Key                      = type.Key;
                typeEntity.Name                     = type.Key;
                typeEntity.DocumentCount            = type.DocCount;
                typeEntity.BucketTransformationType = Enums.BucketTransformationEnum.TermType;
                typeEntity.Childrens                = new List <RequestBucketComposite>();

                if (selectedType.Any())
                {
                    typeEntity.Selected = true;
                }

                var primitiveTypeIdBucket = type.Terms("attribute_type_primitive_type_id");

                if (primitiveTypeIdBucket.Items.Count > 0)
                {
                    var firstTopPrimitive = primitiveTypeIdBucket.Items.First().Key;
                    if (!string.IsNullOrWhiteSpace(firstTopPrimitive))
                    {
                        typeEntity.PrimitiveType = (ItemPrimitiveTypeEnum)Convert.ToInt32(firstTopPrimitive);
                    }
                    else
                    {
                        typeEntity.PrimitiveType = ItemPrimitiveTypeEnum.String;
                    }
                }
                else
                {
                    typeEntity.PrimitiveType = ItemPrimitiveTypeEnum.String;
                }

                switch (typeEntity.PrimitiveType)
                {
                case ItemPrimitiveTypeEnum.String:
                    var typeFilterBucketString = type.Filter("filter_attribute_item_agg_string");
                    var itemsBucketString      = typeFilterBucketString.Terms("attribute_item_agg_string");

                    foreach (var item in itemsBucketString.Items)
                    {
                        var itemEntity = new RequestBucketComposite();
                        itemEntity.DocumentCount            = item.DocCount;
                        itemEntity.BucketTransformationType = Enums.BucketTransformationEnum.TermItem;
                        itemEntity.Key       = item.Key;
                        itemEntity.Name      = item.Key;
                        itemEntity.Childrens = null;

                        if (selectedType.Any())
                        {
                            var selectedItem = selectedType.First().Childrens.Where(x => string.Compare(x.Key, item.Key, true) == 0);
                            itemEntity.Selected = selectedItem.Any();
                        }

                        typeEntity.Childrens.Add(itemEntity);
                    }

                    result.Add(typeEntity);
                    break;

                case ItemPrimitiveTypeEnum.Number:
                    var typeFilterBucketNum = type.Filter("filter_attribute_item_agg_number");
                    var itemsBucketNum      = typeFilterBucketNum.Terms("attribute_item_agg_number");
                    var min   = typeFilterBucketNum.Min("attribute_item_agg_number_min").Value;
                    var max   = typeFilterBucketNum.Min("attribute_item_agg_number_max").Value;
                    var floor = Math.Floor(min.Value);
                    var ceil  = Math.Ceiling(max.Value);

                    typeEntity.MinValue      = min;
                    typeEntity.MaxValue      = max;
                    typeEntity.MinFloorValue = floor;
                    typeEntity.MaxCeilValue  = ceil;

                    foreach (var item in itemsBucketNum.Items)
                    {
                        var itemEntity = new RequestBucketComposite();
                        itemEntity.DocumentCount            = item.DocCount;
                        itemEntity.BucketTransformationType = Enums.BucketTransformationEnum.TermItem;
                        itemEntity.Key       = item.Key;
                        itemEntity.Name      = item.Key;
                        itemEntity.Childrens = null;

                        itemEntity.MinValue      = min;
                        itemEntity.MaxValue      = max;
                        itemEntity.MinFloorValue = floor;
                        itemEntity.MaxCeilValue  = ceil;

                        if (selectedType.Any())
                        {
                            var selectedItem = selectedType.First().Childrens.Where(x => string.Compare(x.Key, item.Key, true) == 0);
                            itemEntity.Selected = selectedItem.Any();
                        }

                        typeEntity.Childrens.Add(itemEntity);
                    }

                    result.Add(typeEntity);
                    break;

                case ItemPrimitiveTypeEnum.Date:
                    var typeFilterBucketDate = type.Filter("filter_attribute_item_agg_date");
                    var itemsBucketDate      = typeFilterBucketDate.Terms("attribute_item_agg_date");

                    foreach (var item in itemsBucketDate.Items)
                    {
                        var itemEntity = new RequestBucketComposite();
                        itemEntity.DocumentCount            = item.DocCount;
                        itemEntity.BucketTransformationType = Enums.BucketTransformationEnum.TermItem;
                        itemEntity.Key       = item.Key;
                        itemEntity.Name      = item.Key;
                        itemEntity.Childrens = null;

                        if (selectedType.Any())
                        {
                            var selectedItem = selectedType.First().Childrens.Where(x => string.Compare(x.Key, item.Key, true) == 0);
                            itemEntity.Selected = selectedItem.Any();
                        }

                        typeEntity.Childrens.Add(itemEntity);
                    }

                    result.Add(typeEntity);
                    break;

                case ItemPrimitiveTypeEnum.Boolean:
                    var typeFilterBucketBool = type.Filter("filter_attribute_item_agg_bool");
                    var itemsBucketBool      = typeFilterBucketBool.Terms("attribute_item_agg_bool");

                    foreach (var item in itemsBucketBool.Items)
                    {
                        var itemEntity = new RequestBucketComposite();
                        itemEntity.DocumentCount            = item.DocCount;
                        itemEntity.BucketTransformationType = Enums.BucketTransformationEnum.TermItem;
                        itemEntity.Key       = item.Key;
                        itemEntity.Name      = item.Key;
                        itemEntity.Childrens = null;

                        if (selectedType.Any())
                        {
                            var selectedItem = selectedType.First().Childrens.Where(x => string.Compare(x.Key, item.Key, true) == 0);
                            itemEntity.Selected = selectedItem.Any();
                        }

                        typeEntity.Childrens.Add(itemEntity);
                    }

                    result.Add(typeEntity);
                    break;

                default:
                    var typeFilterBucketStringDefault = type.Filter("filter_attribute_item_agg_string");
                    var itemsBucketStringDefault      = typeFilterBucketStringDefault.Terms("attribute_item_agg_string");

                    foreach (var item in itemsBucketStringDefault.Items)
                    {
                        var itemEntity = new RequestBucketComposite();
                        itemEntity.DocumentCount            = item.DocCount;
                        itemEntity.BucketTransformationType = Enums.BucketTransformationEnum.TermItem;
                        itemEntity.Key       = item.Key;
                        itemEntity.Name      = item.Key;
                        itemEntity.Childrens = null;

                        if (selectedType.Any())
                        {
                            var selectedItem = selectedType.First().Childrens.Where(x => string.Compare(x.Key, item.Key, true) == 0);
                            itemEntity.Selected = selectedItem.Any();
                        }

                        typeEntity.Childrens.Add(itemEntity);
                    }

                    result.Add(typeEntity);
                    break;
                }
            }

            return(result);
        }