Beispiel #1
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Facet"/> class.
 /// </summary>
 /// <param name="group">The group.</param>
 /// <param name="key">The key.</param>
 /// <param name="count">The count.</param>
 /// <param name="labels">The labels.</param>
 public Facet(FacetGroup group, string key, int count, FacetLabel[] labels)
 {
     Group  = group;
     Key    = key;
     Labels = labels;
     Count  = count;
 }
Beispiel #2
0
        /// <summary>
        /// Using the facets returned with the search results, we can bind some filter dropdowns to the Grade, Type, and Year facets
        /// We must first make sure those facets exist.
        /// </summary>
        protected void BindFilters()
        {
            FacetGroup gradeFacet = this.Results.FacetGroups.SingleOrDefault(facet => facet.FieldName == "Grade");

            if (gradeFacet != null)
            {
                this.ddlGradeFilter.DataSource = gradeFacet.Facets;
                this.ddlGradeFilter.DataBind();
            }
            this.ddlGradeFilter.Items.Insert(0, new ListItem("All Grades"));


            FacetGroup typeFacet = this.Results.FacetGroups.SingleOrDefault(facet => facet.FieldName == "TypeGroup");

            if (typeFacet != null)
            {
                this.ddlTypeFilter.DataSource = typeFacet.Facets;
                this.ddlTypeFilter.DataBind();
            }

            this.ddlTypeFilter.Items.Insert(0, new ListItem("All Types"));

            FacetGroup yearFacet = this.Results.FacetGroups.SingleOrDefault(facet => facet.FieldName == "Year");

            if (yearFacet != null)
            {
                this.ddlYearFilter.DataSource = yearFacet.Facets;
                this.ddlYearFilter.DataBind();
            }
            this.ddlYearFilter.Items.Insert(0, new ListItem("All Years"));
        }
Beispiel #3
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Facet"/> class.
 /// </summary>
 /// <param name="group">The group.</param>
 /// <param name="key">The key.</param>
 /// <param name="name">The name.</param>
 /// <param name="count">The count.</param>
 public Facet(FacetGroup group, string key, string name, int count)
 {
     this.Group = group;
     this.Key   = key;
     this.Name  = name;
     this.Count = count;
 }
Beispiel #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Facet"/> class.
 /// </summary>
 /// <param name="group">The group.</param>
 /// <param name="key">The key.</param>
 /// <param name="count">The count.</param>
 /// <param name="labels">The labels.</param>
 public Facet(FacetGroup group, string key, int count, FacetLabel[] labels)
 {
     Group = group;
     Key = key;
     Labels = labels;
     Count = count;
 }
Beispiel #5
0
        private FacetGroup CalculateResultCount(IndexReader reader, DocIdSet baseDocIdSet, ISearchFilter filter, ISearchCriteria criteria)
        {
            FacetGroup result = null;

            var values = filter.GetValues();

            if (values != null)
            {
                BooleanFilter ffilter = null;
                foreach (var f in criteria.CurrentFilters)
                {
                    if (!f.Key.Equals(filter.Key))
                    {
                        if (ffilter == null)
                        {
                            ffilter = new BooleanFilter();
                        }

                        var q = LuceneQueryHelper.CreateQuery(criteria, f, Occur.SHOULD);
                        ffilter.Add(new FilterClause(q, Occur.MUST));
                    }
                }

                var groupLabels = filter.GetLabels();
                var facetGroup  = new FacetGroup(filter.Key, groupLabels);

                foreach (var group in values.GroupBy(v => v.Id))
                {
                    var value       = group.FirstOrDefault();
                    var valueFilter = LuceneQueryHelper.CreateQueryForValue(Results.SearchCriteria, filter, value);

                    if (valueFilter != null)
                    {
                        var queryFilter = new BooleanFilter();
                        queryFilter.Add(new FilterClause(valueFilter, Occur.MUST));
                        if (ffilter != null)
                        {
                            queryFilter.Add(new FilterClause(ffilter, Occur.MUST));
                        }

                        var filterArray = queryFilter.GetDocIdSet(reader);
                        var newCount    = (int)CalculateFacetCount(baseDocIdSet, filterArray);

                        if (newCount > 0)
                        {
                            var valueLabels = group.GetValueLabels();
                            var newFacet    = new Facet(facetGroup, group.Key, newCount, valueLabels);
                            facetGroup.Facets.Add(newFacet);
                        }
                    }
                }

                if (facetGroup.Facets.Any())
                {
                    result = facetGroup;
                }
            }

            return(result);
        }
Beispiel #6
0
 /// <summary>
 /// Initializes a new instance of the <see cref="Facet"/> class.
 /// </summary>
 /// <param name="group">The group.</param>
 /// <param name="key">The key.</param>
 /// <param name="name">The name.</param>
 /// <param name="count">The count.</param>
 public Facet(FacetGroup group, string key, string name, int count)
 {
     this.Group = group;
     this.Key = key;
     this.Name = name;
     this.Count = count;
 }
Beispiel #7
0
        public IViewComponentResult Invoke(FacetGroup facetGroup, string templateName)
        {
            Guard.NotNull(facetGroup, nameof(facetGroup));
            Guard.NotEmpty(templateName, nameof(templateName));

            return(View(templateName, facetGroup));
        }
Beispiel #8
0
        /// <summary>
        /// Calculates the result count.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="baseDocIdSet">The base doc id set.</param>
        /// <param name="facetGroup">The facet group.</param>
        /// <param name="filter">The filter.</param>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        private int CalculateResultCount(IndexReader reader, DocIdSet baseDocIdSet, FacetGroup facetGroup, ISearchFilter filter, ISearchCriteria criteria)
        {
            var count = 0;

            var values = LuceneQueryHelper.GetFilterValues(filter);

            if (values == null)
            {
                return(0);
            }

            BooleanFilter ffilter = null;

            foreach (var f in criteria.CurrentFilters)
            {
                if (!f.Key.Equals(facetGroup.FieldName))
                {
                    if (ffilter == null)
                    {
                        ffilter = new BooleanFilter();
                    }

                    var q = LuceneQueryHelper.CreateQuery(criteria, f, Occur.SHOULD);
                    ffilter.Add(new FilterClause(q, Occur.MUST));
                }
            }

            foreach (var value in values)
            {
                var queryFilter = new BooleanFilter();

                var valueFilter = LuceneQueryHelper.CreateQueryForValue(Results.SearchCriteria, filter, value);

                if (valueFilter == null)
                {
                    continue;
                }

                queryFilter.Add(new FilterClause(valueFilter, Occur.MUST));
                if (ffilter != null)
                {
                    queryFilter.Add(new FilterClause(ffilter, Occur.MUST));
                }

                var filterArray = queryFilter.GetDocIdSet(reader);
                var newCount    = (int)CalculateFacetCount(baseDocIdSet, filterArray);
                if (newCount == 0)
                {
                    continue;
                }

                var newFacet = new Facet(facetGroup, value.Id, GetDescription(value, Results.SearchCriteria.Locale), newCount);
                facetGroup.Facets.Add(newFacet);
                count += newCount;
            }

            return(count);
        }
        public RouteInfo GetTemplateRoute(FacetGroup facetGroup)
        {
            var route = _selectors
                        .OrderByDescending(x => x.Ordinal)
                        .Select(x => x.GetTemplateRoute(facetGroup))
                        .FirstOrDefault(x => x != null);

            return(route);
        }
 /// <summary>
 /// Converts the specified facet group.
 /// </summary>
 /// <param name="helper">The helper.</param>
 /// <param name="group">The facet group.</param>
 /// <returns>
 /// facet group
 /// </returns>
 public static FilterModel Convert(this ISearchFilterService helper, FacetGroup group)
 {
     return(new FilterModel
     {
         Key = @group.FieldName,
         Name = GetDescriptionFromFilter(@group.FieldName),
         Facets = @group.Facets.Select(x => Convert(helper, x)).ToArray()
     });
 }
        private void AddFacetResult(FacetGroup facetGroup, Dictionary <string, FilterFacet> facetsByName, string field, string key, Descriptions descriptions, string locale)
        {
            string      key1 = FindProviderExtensions.EncodeFacetName(field, key);
            FilterFacet filterFacet;

            if (!facetsByName.TryGetValue(key1, out filterFacet) || filterFacet.Count <= 0)
            {
                return;
            }
            string facetDescription = this.GetFacetDescription(descriptions, locale);

            Mediachase.Search.Extensions.Facet facet = new Mediachase.Search.Extensions.Facet((ISearchFacetGroup)facetGroup, key, facetDescription, filterFacet.Count);
            facetGroup.Facets.Add((ISearchFacet)facet);
        }
Beispiel #12
0
        public static Aggregation ToModuleModel(this FacetGroup facetGroup, params string[] appliedFilters)
        {
            var result = new Aggregation
            {
                AggregationType = facetGroup.FacetType,
                Field           = facetGroup.FieldName,
                Items           = facetGroup.Facets.Select(f => f.ToModuleModel(appliedFilters)).ToArray()
            };

            if (facetGroup.Labels != null)
            {
                result.Labels = facetGroup.Labels.Select(ToModuleModel).ToArray();
            }

            return(result);
        }
Beispiel #13
0
        /// <summary>
        /// Converts the browser request to facet groups and optionally looks up a display label for the facet value if a facetDisplayDictionaryValues is passed and has a value for the facet alias
        /// </summary>
        /// <param name="facetMap"></param>
        /// <param name="facetDisplayDictionaryValues"></param>
        /// <returns></returns>
        public virtual IEnumerable <FacetGroup> ConvertToFacetGroups(Dictionary <string, IFacetAccessible> facetMap, Dictionary <string, Dictionary <string, string> > facetDisplayDictionaryValues = null)
        {
            var facetGroups = new List <FacetGroup>();

            if (facetMap.Any())
            {
                foreach (var map in facetMap)
                {
                    var facetField = FacetFields.FirstOrDefault(x => map.Key == x.Alias.FacetFieldAlias());
                    var group      = new FacetGroup
                    {
                        Label = facetField?.Label,
                        Alias = map.Key
                    };
                    var sortOrder = 0;
                    foreach (var f in map.Value.GetFacets())
                    {
                        var facetName = f.Value.ToString();
                        sortOrder++;
                        if (facetDisplayDictionaryValues != null)
                        {
                            if (facetDisplayDictionaryValues.ContainsKey(map.Key) &&
                                facetDisplayDictionaryValues[map.Key].ContainsKey(f.Value.ToString()))
                            {
                                facetName = facetDisplayDictionaryValues[map.Key][f.Value.ToString()];
                            }
                        }
                        else if (facetField != null)
                        {
                            facetName = facetField.CreateValueLabel(f.Value.ToString());
                        }

                        var facet = new Facet
                        {
                            Label = facetName,
                            Value = f.Value.ToString(),
                            Count = f.HitCount,
                            Sort  = sortOrder
                        };
                        group.Facets.Add(facet);
                    }

                    facetGroups.Add(group);
                }
            }
            return(facetGroups);
        }
        public RouteInfo GetTemplateRoute(FacetGroup facetGroup)
        {
            var templateName = GetTemplateName(facetGroup);

            if (templateName.IsEmpty())
            {
                return(null);
            }

            string controller  = "Search";
            string action      = "FacetGroup";
            var    routeValues = new RouteValueDictionary(new
            {
                area         = "",
                facetGroup   = facetGroup,
                templateName = templateName
            });

            return(new RouteInfo(action, controller, routeValues));
        }
 public virtual Facet FakeFacet(
     string facetCode,
     FacetType t,
     FacetGroup g,
     bool is_applicable = true
     ) =>
 new Facet
 {
     FacetCode        = facetCode,
     CategoryIdExpr   = Guid.NewGuid().ToString(),
     CategoryNameExpr = Guid.NewGuid().ToString(),
     Description      = Guid.NewGuid().ToString(),
     DisplayTitle     = Guid.NewGuid().ToString(),
     AggregateType    = "",
     AggregateTitle   = "",
     AggregateFacetId = 0,
     SortExpr         = "",
     FacetGroup       = g,
     FacetType        = t,
     IsApplicable     = is_applicable
 };
        private IEnumerable <FacetGroup> BuildFacetResults(SearchResults <FindDocument> results, ISearchCriteria criteria)
        {
            List <FacetGroup> facetGroupList = new List <FacetGroup>();

            if (results.Facets != null && results.Facets.Any <EPiServer.Find.Api.Facets.Facet>())
            {
                Dictionary <string, FilterFacet> dictionary = results.Facets.OfType <FilterFacet>().ToDictionary <FilterFacet, string, FilterFacet>((Func <FilterFacet, string>)(f => f.Name), (Func <FilterFacet, FilterFacet>)(f => f), (IEqualityComparer <string>)StringComparer.OrdinalIgnoreCase);
                foreach (SearchFilter filter in criteria.Filters)
                {
                    string     facetDescription = this.GetFacetDescription(filter.Descriptions, criteria.Locale);
                    FacetGroup facetGroup       = new FacetGroup(filter.field, facetDescription);
                    if (filter.Values.SimpleValue != null)
                    {
                        foreach (SimpleValue simpleValue in filter.Values.SimpleValue)
                        {
                            this.AddFacetResult(facetGroup, dictionary, filter.field, simpleValue.key, simpleValue.Descriptions, criteria.Locale);
                        }
                    }
                    if (filter.Values.RangeValue != null)
                    {
                        foreach (RangeValue rangeValue in filter.Values.RangeValue)
                        {
                            this.AddFacetResult(facetGroup, dictionary, filter.field, rangeValue.key, rangeValue.Descriptions, criteria.Locale);
                        }
                    }
                    if (filter.Values.PriceRangeValue != null)
                    {
                        foreach (PriceRangeValue priceRangeValue in ((IEnumerable <PriceRangeValue>)filter.Values.PriceRangeValue).Where <PriceRangeValue>((Func <PriceRangeValue, bool>)(prv => string.Equals(prv.currency, (string)criteria.Currency, StringComparison.OrdinalIgnoreCase))))
                        {
                            this.AddFacetResult(facetGroup, dictionary, filter.field, priceRangeValue.key, priceRangeValue.Descriptions, criteria.Locale);
                        }
                    }
                    if (facetGroup.Facets.Count > 0)
                    {
                        facetGroupList.Add(facetGroup);
                    }
                }
            }
            return((IEnumerable <FacetGroup>)facetGroupList);
        }
Beispiel #17
0
        private string GetTemplateName(FacetGroup group)
        {
            var prefix = "FacetTemplates/";

            switch (group.Kind)
            {
            case FacetGroupKind.Category:
            case FacetGroupKind.DeliveryTime:
            case FacetGroupKind.Brand:
            case FacetGroupKind.Availability:
            case FacetGroupKind.NewArrivals:
                return(prefix + (group.IsMultiSelect ? "MultiSelect" : "SingleSelect"));

            case FacetGroupKind.Price:
                return(prefix + "Price");

            case FacetGroupKind.Rating:
                return(prefix + "Rating");
            }

            return(null);
        }
        public RouteInfo GetTemplateRoute(FacetGroup facetGroup)
        {
            // Provide template for catalog only.
            if (facetGroup.Scope != "Catalog")
            {
                return(null);
            }

            // Provide template for specifications attributes only.
            if (facetGroup.Kind != FacetGroupKind.Attribute)
            {
                return(null);
            }

            // Provide template for admin only (because this is a developer demo).
            if (!_workContext.CurrentCustomer.IsAdmin())
            {
                return(null);
            }

            // TODO: filter by what your template is made for.
            // E.g. merchant configures a specification attribute in your plugin, then you can filter by facetGroup.Key == "attrid<ConfiguredId>"

            if (facetGroup.Label.IsCaseInsensitiveEqual("Dimensions") ||
                facetGroup.Label.IsCaseInsensitiveEqual("Maße"))
            {
                var routeValues = new RouteValueDictionary(new
                {
                    area         = "SmartStore.DevTools",
                    templateName = "MyCustomFacetTemplate",
                    facetGroup
                });

                return(new RouteInfo("MyCustomFacetTemplate", "DevTools", routeValues));
            }

            return(null);
        }
 public void Init()
 {
     instance = new FacetGroup();
 }
        /// <summary>
        /// Creates facets.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="query">The query.</param>
        private void CreateFacets(IndexReader reader, Query query)
        {
            var groups = new List<FacetGroup>();
            var baseQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(query));
            var baseDocIdSet = baseQueryFilter.GetDocIdSet(reader);

            #region Subcategory filters

           
            /* 
            var catalogCriteria = Results.SearchCriteria as CatalogItemSearchCriteria;
            if (catalogCriteria != null && catalogCriteria.ChildCategoryFilters.Any())
            {
                var group = new FacetGroup("Subcategory");
                var groupCount = 0;

                foreach (var value in catalogCriteria.ChildCategoryFilters)
                {
                    var q = LuceneQueryHelper.CreateQuery(catalogCriteria.OutlineField, value);

                    if (q == null) continue;

                    var queryFilter = new CachingWrapperFilter(new QueryWrapperFilter(q));
                    var filterArray = queryFilter.GetDocIdSet(reader);
                    var newCount = (int)CalculateFacetCount(baseDocIdSet, filterArray);
                    if (newCount == 0) continue;

                    var newFacet = new Facet(group, value.Code, value.Name, newCount);
                    group.Facets.Add(newFacet);
                    groupCount += newCount;
                }

                // Add only if items exist under
                if (groupCount > 0)
                {
                    groups.Add(group);
                }
            }
             * */

            #endregion

            if (Results.SearchCriteria.Filters != null && Results.SearchCriteria.Filters.Length > 0)
            {
                foreach (var filter in Results.SearchCriteria.Filters)
                {
                    var group = new FacetGroup(filter.Key);
                    var groupCount = 0;

                    if (!String.IsNullOrEmpty(Results.SearchCriteria.Currency) && filter is s.PriceRangeFilter)
                    {
                        var valCurrency = ((s.PriceRangeFilter) filter).Currency;
                        if (
                            !valCurrency.Equals(
                                Results.SearchCriteria.Currency, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    }

                    groupCount += CalculateResultCount(reader, baseDocIdSet, group, filter,
                        Results.SearchCriteria);

                    // Add only if items exist under
                    if (groupCount > 0)
                    {
                        groups.Add(group);
                    }
                }
            }

            Results.FacetGroups = groups.ToArray();
        }
        /// <summary>
        /// Calculates the result count.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="baseDocIdSet">The base doc id set.</param>
        /// <param name="facetGroup">The facet group.</param>
        /// <param name="filter">The filter.</param>
        /// <param name="criteria">The criteria.</param>
        /// <returns></returns>
        private int CalculateResultCount(IndexReader reader, DocIdSet baseDocIdSet, FacetGroup facetGroup, ISearchFilter filter, ISearchCriteria criteria)
        {
            var count = 0;

            var values = LuceneQueryHelper.GetFilterValues(filter);

            if (values == null)
            {
                return 0;
            }

            BooleanFilter ffilter = null;
            foreach (var f in criteria.CurrentFilters)
            {
                if (!f.Key.Equals(facetGroup.FieldName))
                {
                    if (ffilter == null) ffilter = new BooleanFilter();

                    var q = LuceneQueryHelper.CreateQuery(criteria, f, Occur.SHOULD);
                    ffilter.Add(new FilterClause(q, Occur.MUST));
                }
            }

            foreach (var value in values)
            {
                var queryFilter = new BooleanFilter();
                    
                var valueFilter = LuceneQueryHelper.CreateQueryForValue(Results.SearchCriteria, filter, value);

                if (valueFilter == null) continue;

                queryFilter.Add(new FilterClause(valueFilter, Occur.MUST));
                if(ffilter!=null)
                    queryFilter.Add(new FilterClause(ffilter, Occur.MUST));

                var filterArray = queryFilter.GetDocIdSet(reader);
                var newCount = (int)CalculateFacetCount(baseDocIdSet, filterArray);
                if (newCount == 0) continue;

                var newFacet = new Facet(facetGroup, value.Id, GetDescription(value, Results.SearchCriteria.Locale), newCount);
                facetGroup.Facets.Add(newFacet);
                count += newCount;
            }

            return count;
        }
Beispiel #22
0
        public virtual ISearchResults Search(string scope, ISearchCriteria criteria)
        {
            var command = new SearchCommand(scope, criteria.DocumentType);

            command.Size(criteria.RecordsToRetrieve);
            command.From(criteria.StartingRecord);

            // Add spell checking
            // TODO: options.SpellCheck = new SpellCheckingParameters { Collate = true };

            // Build query
            var builder = (QueryBuilder <ESDocument>)_queryBuilder.BuildQuery(criteria);

            SearchResult <ESDocument> resultDocs;

            // Add some error handling
            try
            {
                resultDocs = Client.Search(command, builder);
            }
            catch (Exception ex)
            {
                throw new ElasticSearchException("Search using Elastic Search server failed, check logs for more details.", ex);
            }

            // Parse documents returned
            var documents = new ResultDocumentSet {
                TotalCount = resultDocs.hits.total
            };
            var docList = new List <ResultDocument>();

            foreach (var indexDoc in resultDocs.Documents)
            {
                var document = new ResultDocument();
                foreach (var field in indexDoc.Keys)
                {
                    document.Add(new DocumentField(field, indexDoc[field]));
                }

                docList.Add(document);
            }

            documents.Documents = docList.ToArray();

            // Create search results object
            var results = new SearchResults(criteria, new[] { documents });

            // Now add facet results
            var groups = new List <FacetGroup>();

            if (resultDocs.facets != null)
            {
                foreach (var filter in criteria.Filters)
                {
                    var groupCount = 0;

                    var group = new FacetGroup(filter.Key);

                    if (filter is AttributeFilter)
                    {
                        var attributeFilter = filter as AttributeFilter;
                        var myFilter        = attributeFilter;
                        var values          = myFilter.Values;
                        if (values != null)
                        {
                            var key = filter.Key.ToLower();
                            if (!resultDocs.facets.ContainsKey(key))
                            {
                                continue;
                            }

                            var facet = resultDocs.facets[key] as TermsFacetResult;
                            if (facet != null)
                            {
                                foreach (var value in values)
                                {
                                    //facet.terms
                                    var termCount = from f in facet.terms where f.term.Equals(value.Id, StringComparison.OrdinalIgnoreCase) select f.count;

                                    var enumerable = termCount as int[] ?? termCount.ToArray();
                                    if (!enumerable.Any())
                                    {
                                        continue;
                                    }

                                    //var facet = from resultFacet
                                    var newFacet = new Facet(@group, value.Id, GetDescription(value, criteria.Locale), enumerable.SingleOrDefault());
                                    @group.Facets.Add(newFacet);
                                }

                                groupCount++;
                            }
                        }
                    }
                    else if (filter is PriceRangeFilter)
                    {
                        var rangeFilter = filter as PriceRangeFilter;
                        if (rangeFilter != null &&
                            rangeFilter.Currency.Equals(criteria.Currency, StringComparison.OrdinalIgnoreCase))
                        {
                            var myFilter = rangeFilter;
                            var values   = myFilter.Values;
                            if (values != null)
                            {
                                values = rangeFilter.Values;

                                foreach (var value in values)
                                {
                                    var key = String.Format("{0}-{1}", myFilter.Key, value.Id).ToLower();

                                    if (!resultDocs.facets.ContainsKey(key))
                                    {
                                        continue;
                                    }

                                    var facet = resultDocs.facets[key] as FilterFacetResult;

                                    if (facet != null && facet.count > 0)
                                    {
                                        if (facet.count == 0)
                                        {
                                            continue;
                                        }

                                        var myFacet = new Facet(
                                            @group, value.Id, GetDescription(value, criteria.Locale), facet.count);
                                        @group.Facets.Add(myFacet);

                                        groupCount++;
                                    }
                                }
                            }
                        }
                    }
                    else if (filter is RangeFilter)
                    {
                        var myFilter = filter as RangeFilter;
                        if (myFilter != null)
                        {
                            var values = myFilter.Values;
                            if (values != null)
                            {
                                foreach (var value in values)
                                {
                                    var facet = resultDocs.facets[filter.Key] as FilterFacetResult;

                                    if (facet == null || facet.count <= 0)
                                    {
                                        continue;
                                    }

                                    var myFacet = new Facet(
                                        @group, value.Id, GetDescription(value, criteria.Locale), facet.count);
                                    @group.Facets.Add(myFacet);

                                    groupCount++;
                                }
                            }
                        }
                    }
                    else if (filter is CategoryFilter)
                    {
                        var myFilter = filter as CategoryFilter;
                        if (myFilter != null)
                        {
                            var values = myFilter.Values;
                            if (values != null)
                            {
                                foreach (var value in values)
                                {
                                    var key   = String.Format("{0}-{1}", myFilter.Key.ToLower(), value.Id.ToLower()).ToLower();
                                    var facet = resultDocs.facets[key] as FilterFacetResult;

                                    if (facet == null || facet.count <= 0)
                                    {
                                        continue;
                                    }

                                    var myFacet = new Facet(
                                        @group, value.Id, GetDescription(value, criteria.Locale), facet.count);
                                    @group.Facets.Add(myFacet);

                                    groupCount++;
                                }
                            }
                        }
                    }

                    // Add only if items exist under
                    if (groupCount > 0)
                    {
                        groups.Add(group);
                    }
                }
            }

            results.FacetGroups = groups.ToArray();
            return(results);
        }
 public ActionResult MyCustomFacetTemplate(FacetGroup facetGroup, string templateName)
 {
     /// Just a "proxy" for our <see cref="Services.CustomFacetTemplateSelector" />.
     return(PartialView(templateName, facetGroup));
 }
Beispiel #24
0
        protected virtual IDictionary <string, FacetGroup> GetFacets(CatalogSearchQuery searchQuery, int totalHits)
        {
            var result     = new Dictionary <string, FacetGroup>();
            var languageId = searchQuery.LanguageId ?? _services.WorkContext.WorkingLanguage.Id;

            foreach (var key in searchQuery.FacetDescriptors.Keys)
            {
                var descriptor = searchQuery.FacetDescriptors[key];
                var facets     = new List <Facet>();
                var kind       = FacetGroup.GetKindByKey(key);

                if (kind == FacetGroupKind.Category)
                {
                    #region Category

                    // order by product count
                    var categoryQuery =
                        from c in _categoryRepository.TableUntracked
                        where !c.Deleted && c.Published
                        join pc in _productCategoryRepository.TableUntracked on c.Id equals pc.CategoryId into pcm
                        from pc in pcm.DefaultIfEmpty()
                        group c by c.Id into grp
                        orderby grp.Count() descending
                        select new
                    {
                        Id           = grp.FirstOrDefault().Id,
                        Name         = grp.FirstOrDefault().Name,
                        DisplayOrder = grp.FirstOrDefault().DisplayOrder
                    };

                    if (descriptor.MaxChoicesCount > 0)
                    {
                        categoryQuery = categoryQuery.Take(descriptor.MaxChoicesCount);
                    }

                    var categories = categoryQuery.ToList();

                    var nameQuery = _localizedPropertyRepository.TableUntracked
                                    .Where(x => x.LocaleKeyGroup == "Category" && x.LocaleKey == "Name" && x.LanguageId == languageId);

                    var names = nameQuery.ToList().ToDictionarySafe(x => x.EntityId, x => x.LocaleValue);

                    foreach (var category in categories)
                    {
                        var selected = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(category.Id));
                        if (totalHits == 0 && !selected)
                        {
                            continue;
                        }

                        string label = null;
                        names.TryGetValue(category.Id, out label);

                        facets.Add(new Facet(new FacetValue(category.Id, IndexTypeCode.Int32)
                        {
                            IsSelected   = selected,
                            Label        = label.HasValue() ? label : category.Name,
                            DisplayOrder = category.DisplayOrder
                        }));
                    }

                    #endregion
                }
                else if (kind == FacetGroupKind.Brand)
                {
                    #region Brand

                    // order by product count
                    var manufacturerQuery =
                        from m in _manufacturerRepository.TableUntracked
                        where !m.Deleted && m.Published
                        join pm in _productManufacturerRepository.TableUntracked on m.Id equals pm.ManufacturerId into pmm
                        from pm in pmm.DefaultIfEmpty()
                        group m by m.Id into grp
                        orderby grp.Count() descending
                        select new
                    {
                        Id           = grp.FirstOrDefault().Id,
                        Name         = grp.FirstOrDefault().Name,
                        DisplayOrder = grp.FirstOrDefault().DisplayOrder
                    };

                    if (descriptor.MaxChoicesCount > 0)
                    {
                        manufacturerQuery = manufacturerQuery.Take(descriptor.MaxChoicesCount);
                    }

                    var manufacturers = manufacturerQuery.ToList();

                    var nameQuery = _localizedPropertyRepository.TableUntracked
                                    .Where(x => x.LocaleKeyGroup == "Manufacturer" && x.LocaleKey == "Name" && x.LanguageId == languageId);

                    var names = nameQuery.ToList().ToDictionarySafe(x => x.EntityId, x => x.LocaleValue);

                    foreach (var manu in manufacturers)
                    {
                        var selected = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(manu.Id));
                        if (totalHits == 0 && !selected)
                        {
                            continue;
                        }

                        string label = null;
                        names.TryGetValue(manu.Id, out label);

                        facets.Add(new Facet(new FacetValue(manu.Id, IndexTypeCode.Int32)
                        {
                            IsSelected   = selected,
                            Label        = label.HasValue() ? label : manu.Name,
                            DisplayOrder = manu.DisplayOrder
                        }));
                    }

                    #endregion
                }
                else if (kind == FacetGroupKind.DeliveryTime)
                {
                    #region Delivery time

                    var deliveryTimes = _deliveryTimeService.GetAllDeliveryTimes();

                    var nameQuery = _localizedPropertyRepository.TableUntracked
                                    .Where(x => x.LocaleKeyGroup == "DeliveryTime" && x.LocaleKey == "Name" && x.LanguageId == languageId);

                    var names = nameQuery.ToList().ToDictionarySafe(x => x.EntityId, x => x.LocaleValue);

                    foreach (var deliveryTime in deliveryTimes)
                    {
                        if (descriptor.MaxChoicesCount > 0 && facets.Count >= descriptor.MaxChoicesCount)
                        {
                            break;
                        }

                        var selected = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(deliveryTime.Id));
                        if (totalHits == 0 && !selected)
                        {
                            continue;
                        }

                        string label = null;
                        names.TryGetValue(deliveryTime.Id, out label);

                        facets.Add(new Facet(new FacetValue(deliveryTime.Id, IndexTypeCode.Int32)
                        {
                            IsSelected   = selected,
                            Label        = label.HasValue() ? label : deliveryTime.Name,
                            DisplayOrder = deliveryTime.DisplayOrder
                        }));
                    }

                    #endregion
                }
                else if (kind == FacetGroupKind.Price)
                {
                    #region Price

                    var count = 0;
                    var hasActivePredefinedFacet = false;
                    var minPrice = _productRepository.Table.Where(x => !x.Deleted && x.Published).Min(x => (double)x.Price);
                    var maxPrice = _productRepository.Table.Where(x => !x.Deleted && x.Published).Max(x => (double)x.Price);
                    minPrice = FacetUtility.MakePriceEven(minPrice);
                    maxPrice = FacetUtility.MakePriceEven(maxPrice);

                    for (var i = 0; i < _priceThresholds.Length; ++i)
                    {
                        if (descriptor.MaxChoicesCount > 0 && facets.Count >= descriptor.MaxChoicesCount)
                        {
                            break;
                        }

                        var price = _priceThresholds[i];
                        if (price < minPrice)
                        {
                            continue;
                        }

                        if (price >= maxPrice)
                        {
                            i = int.MaxValue - 1;
                        }

                        var selected = descriptor.Values.Any(x => x.IsSelected && x.Value == null && x.UpperValue != null && (double)x.UpperValue == price);
                        if (totalHits == 0 && !selected)
                        {
                            continue;
                        }

                        if (selected)
                        {
                            hasActivePredefinedFacet = true;
                        }

                        facets.Add(new Facet(new FacetValue(null, price, IndexTypeCode.Double, false, true)
                        {
                            DisplayOrder = ++count,
                            IsSelected   = selected
                        }));
                    }

                    // Add facet for custom price range.
                    var priceDescriptorValue = descriptor.Values.FirstOrDefault();

                    var customPriceFacetValue = new FacetValue(
                        priceDescriptorValue != null && !hasActivePredefinedFacet ? priceDescriptorValue.Value : null,
                        priceDescriptorValue != null && !hasActivePredefinedFacet ? priceDescriptorValue.UpperValue : null,
                        IndexTypeCode.Double,
                        true,
                        true);

                    customPriceFacetValue.IsSelected = customPriceFacetValue.Value != null || customPriceFacetValue.UpperValue != null;

                    if (!(totalHits == 0 && !customPriceFacetValue.IsSelected))
                    {
                        facets.Insert(0, new Facet("custom", customPriceFacetValue));
                    }

                    #endregion
                }
                else if (kind == FacetGroupKind.Rating)
                {
                    if (totalHits == 0 && !descriptor.Values.Any(x => x.IsSelected))
                    {
                        continue;
                    }

                    foreach (var rating in FacetUtility.GetRatings())
                    {
                        var newFacet = new Facet(rating);
                        newFacet.Value.IsSelected = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(rating.Value));
                        facets.Add(newFacet);
                    }
                }
                else if (kind == FacetGroupKind.Availability || kind == FacetGroupKind.NewArrivals)
                {
                    var value = descriptor.Values.FirstOrDefault();
                    if (value != null && !(totalHits == 0 && !value.IsSelected))
                    {
                        var newValue = value.Clone();
                        newValue.Value      = true;
                        newValue.TypeCode   = IndexTypeCode.Boolean;
                        newValue.IsRange    = false;
                        newValue.IsSelected = value.IsSelected;

                        facets.Add(new Facet(newValue));
                    }
                }

                if (facets.Any(x => x.Published))
                {
                    //facets.Each(x => $"{key} {x.Value.ToString()}".Dump());

                    result.Add(key, new FacetGroup(
                                   key,
                                   descriptor.Label,
                                   descriptor.IsMultiSelect,
                                   descriptor.DisplayOrder,
                                   facets.OrderBy(descriptor)));
                }
            }

            return(result);
        }
        private static FacetGroup[] CreateFacets(ISearchCriteria criteria, SearchResult <ESDocument> .SearchFacets facets)
        {
            var result = new List <FacetGroup>();

            if (facets != null)
            {
                foreach (var filter in criteria.Filters)
                {
                    var groupLabels = filter.GetLabels();
                    var facetGroup  = new FacetGroup(filter.Key, groupLabels);

                    var values = filter.GetValues();

                    // Return all facet terms for attribute filter if values are not defined
                    if (values == null && filter is AttributeFilter)
                    {
                        facetGroup.FacetType = FacetTypes.Attribute;

                        var key = filter.Key.ToLower();
                        if (facets.ContainsKey(key))
                        {
                            var facet = facets[key] as TermsFacetResult;
                            if (facet != null)
                            {
                                foreach (var term in facet.terms)
                                {
                                    var newFacet = new Facet(facetGroup, term.term, term.count, null);
                                    facetGroup.Facets.Add(newFacet);
                                }
                            }
                        }
                    }

                    if (values != null)
                    {
                        foreach (var group in values.GroupBy(v => v.Id))
                        {
                            var valueLabels = group.GetValueLabels();

                            if (filter is AttributeFilter)
                            {
                                facetGroup.FacetType = FacetTypes.Attribute;

                                var key = filter.Key.ToLower();
                                if (facets.ContainsKey(key))
                                {
                                    var facet = facets[key] as TermsFacetResult;
                                    if (facet != null)
                                    {
                                        var term = facet.terms.FirstOrDefault(t => t.term.Equals(group.Key, StringComparison.OrdinalIgnoreCase));
                                        if (term != null)
                                        {
                                            var newFacet = new Facet(facetGroup, group.Key, term.count, valueLabels);
                                            facetGroup.Facets.Add(newFacet);
                                        }
                                    }
                                }
                            }
                            else if (filter is PriceRangeFilter)
                            {
                                facetGroup.FacetType = FacetTypes.PriceRange;

                                var rangeFilter = filter as PriceRangeFilter;
                                if (rangeFilter.Currency.Equals(criteria.Currency, StringComparison.OrdinalIgnoreCase))
                                {
                                    var key = string.Format(CultureInfo.InvariantCulture, "{0}-{1}", filter.Key, group.Key).ToLower();
                                    if (facets.ContainsKey(key))
                                    {
                                        var facet = facets[key] as FilterFacetResult;
                                        if (facet != null && facet.count > 0)
                                        {
                                            var newFacet = new Facet(facetGroup, group.Key, facet.count, valueLabels);
                                            facetGroup.Facets.Add(newFacet);
                                        }
                                    }
                                }
                            }
                            else if (filter is RangeFilter)
                            {
                                facetGroup.FacetType = FacetTypes.Range;

                                var key = filter.Key.ToLower();
                                if (facets.ContainsKey(key))
                                {
                                    var facet = facets[key] as FilterFacetResult;
                                    if (facet != null && facet.count > 0)
                                    {
                                        var newFacet = new Facet(facetGroup, group.Key, facet.count, valueLabels);
                                        facetGroup.Facets.Add(newFacet);
                                    }
                                }
                            }
                            else if (filter is CategoryFilter)
                            {
                                facetGroup.FacetType = FacetTypes.Category;

                                var key = string.Format(CultureInfo.InvariantCulture, "{0}-{1}", filter.Key, group.Key).ToLower();
                                if (facets.ContainsKey(key))
                                {
                                    var facet = facets[key] as FilterFacetResult;
                                    if (facet != null && facet.count > 0)
                                    {
                                        var newFacet = new Facet(facetGroup, group.Key, facet.count, valueLabels);
                                        facetGroup.Facets.Add(newFacet);
                                    }
                                }
                            }
                        }
                    }

                    // Add facet group only if has items
                    if (facetGroup.Facets.Any())
                    {
                        result.Add(facetGroup);
                    }
                }
            }

            return(result.ToArray());
        }
Beispiel #26
0
        public async Task <SearchResult <T> > SearchAsync(SearchQuery queryDefinition, CancellationToken cancellationToken = default)
        {
            using (await writerLock.ReaderLockAsync(cancellationToken))
            {
                var      result = new SearchResult <T>();
                List <T> hits   = new List <T>();

                using (var writer = getWriter())
                {
                    Query query = new MatchAllDocsQuery();

                    // Term queries
                    if (queryDefinition.TermQueries.Any())
                    {
                        var phraseQuery = new MultiPhraseQuery();
                        foreach (var termQuery in queryDefinition.TermQueries)
                        {
                            phraseQuery.Add(
                                termQuery.value
                                .Split(" ".ToCharArray(), StringSplitOptions.RemoveEmptyEntries)
                                .Select(phrase => new Term(termQuery.field, phrase.ToLower()))
                                .ToArray()
                                );
                        }
                        query = phraseQuery;
                    }

                    var reader       = writer.DocsWriter.GetReader(applyAllDeletes: true);
                    var searcher     = new IndexSearcher(reader);
                    var luceneResult = searcher.Search(query, queryDefinition.Limit);

                    foreach (var doc in luceneResult.ScoreDocs)
                    {
                        var foundDoc = searcher.Doc(doc.Doc);
                        hits.Add(await inflateDocument(foundDoc));
                    }

                    result.TotalHits = luceneResult.TotalHits;
                    result.Hits      = hits;

                    // Facets
                    if (queryDefinition.Facets.Any())
                    {
                        FacetsConfig    facetsConfig = new FacetsConfig();
                        FacetsCollector fc           = new FacetsCollector();
                        FacetsCollector.Search(searcher, query, queryDefinition.FacetMax, fc);
                        using (var taxonomyReader = new DirectoryTaxonomyReader(FSDirectory.Open(Path.Combine(options.IndexPath, indexType, "taxonomy"))))
                        {
                            var facets = new FastTaxonomyFacetCounts(taxonomyReader, facetsConfig, fc);
                            foreach (var facet in queryDefinition.Facets)
                            {
                                var facetGroup = new FacetGroup {
                                    Field = facet
                                };
                                facetGroup.Facets =
                                    facets.GetTopChildren(queryDefinition.FacetMax, facet).LabelValues
                                    .Select(x => new Facet {
                                    Key = x.Label, Count = (long)x.Value
                                })
                                    .ToArray();
                                result.FacetGroups.Add(facetGroup);
                            }
                        }
                    }
                }

                return(result);
            }
        }
Beispiel #27
0
        /// <summary>
        /// Creates facets.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="query">The query.</param>
        private void CreateFacets(IndexReader reader, Query query)
        {
            var groups          = new List <FacetGroup>();
            var baseQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(query));
            var baseDocIdSet    = baseQueryFilter.GetDocIdSet(reader);

            #region Subcategory filters


            /*
             * var catalogCriteria = Results.SearchCriteria as CatalogItemSearchCriteria;
             * if (catalogCriteria != null && catalogCriteria.ChildCategoryFilters.Any())
             * {
             *  var group = new FacetGroup("Subcategory");
             *  var groupCount = 0;
             *
             *  foreach (var value in catalogCriteria.ChildCategoryFilters)
             *  {
             *      var q = LuceneQueryHelper.CreateQuery(catalogCriteria.OutlineField, value);
             *
             *      if (q == null) continue;
             *
             *      var queryFilter = new CachingWrapperFilter(new QueryWrapperFilter(q));
             *      var filterArray = queryFilter.GetDocIdSet(reader);
             *      var newCount = (int)CalculateFacetCount(baseDocIdSet, filterArray);
             *      if (newCount == 0) continue;
             *
             *      var newFacet = new Facet(group, value.Code, value.Name, newCount);
             *      group.Facets.Add(newFacet);
             *      groupCount += newCount;
             *  }
             *
             *  // Add only if items exist under
             *  if (groupCount > 0)
             *  {
             *      groups.Add(group);
             *  }
             * }
             * */

            #endregion

            if (Results.SearchCriteria.Filters != null && Results.SearchCriteria.Filters.Length > 0)
            {
                foreach (var filter in Results.SearchCriteria.Filters)
                {
                    var group      = new FacetGroup(filter.Key);
                    var groupCount = 0;

                    if (!String.IsNullOrEmpty(Results.SearchCriteria.Currency) && filter is PriceRangeFilter)
                    {
                        var valCurrency = ((PriceRangeFilter)filter).Currency;
                        if (
                            !valCurrency.Equals(
                                Results.SearchCriteria.Currency, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    }

                    groupCount += CalculateResultCount(reader, baseDocIdSet, group, filter,
                                                       Results.SearchCriteria);

                    // Add only if items exist under
                    if (groupCount > 0)
                    {
                        groups.Add(group);
                    }
                }
            }

            Results.FacetGroups = groups.ToArray();
        }
        private FacetGroup CalculateResultCount(IndexReader reader, DocIdSet baseDocIdSet, ISearchFilter filter, ISearchCriteria criteria)
        {
            FacetGroup result = null;

            var values = filter.GetValues();
            if (values != null)
            {
                BooleanFilter ffilter = null;
                foreach (var f in criteria.CurrentFilters)
                {
                    if (!f.Key.Equals(filter.Key))
                    {
                        if (ffilter == null)
                            ffilter = new BooleanFilter();

                        var q = LuceneQueryHelper.CreateQuery(criteria, f, Occur.SHOULD);
                        ffilter.Add(new FilterClause(q, Occur.MUST));
                    }
                }

                var groupLabels = filter.GetLabels();
                var facetGroup = new FacetGroup(filter.Key, groupLabels);

                foreach (var group in values.GroupBy(v => v.Id))
                {
                    var value = group.FirstOrDefault();
                    var valueFilter = LuceneQueryHelper.CreateQueryForValue(Results.SearchCriteria, filter, value);

                    if (valueFilter != null)
                    {
                        var queryFilter = new BooleanFilter();
                        queryFilter.Add(new FilterClause(valueFilter, Occur.MUST));
                        if (ffilter != null)
                            queryFilter.Add(new FilterClause(ffilter, Occur.MUST));

                        var filterArray = queryFilter.GetDocIdSet(reader);
                        var newCount = (int)CalculateFacetCount(baseDocIdSet, filterArray);

                        if (newCount > 0)
                        {
                            var valueLabels = group.GetValueLabels();
                            var newFacet = new Facet(facetGroup, group.Key, newCount, valueLabels);
                            facetGroup.Facets.Add(newFacet);
                        }
                    }
                }

                if (facetGroup.Facets.Any())
                {
                    result = facetGroup;
                }
            }

            return result;
        }
        /// <summary>
        /// Converts the specified facet group.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <param name="group">The facet group.</param>
        /// <returns>
        /// facet group
        /// </returns>
	    public static FilterModel Convert(this SearchHelper helper, FacetGroup group)
		{
			return new FilterModel
			{
				Key = @group.FieldName,
				Name = GetDescriptionFromFilter(helper, @group.FieldName),
                Facets = @group.Facets.Select(x => Convert(helper, x)).ToArray()
			};
		}
        /// <summary>
        /// Converts the specified facet groups into filter model.
        /// </summary>
        /// <param name="helper">The helper.</param>
        /// <param name="groups">The groups.</param>
        /// <returns>
        /// FilterModel[][].
        /// </returns>
	    public static FilterModel[] Convert(this SearchHelper helper, FacetGroup[] groups)
		{
			var list = new List<FilterModel>();
			if (groups != null)
			{
                list.AddRange(groups.Select(x => Convert(helper, x)));
			}

			return list.ToArray();
		}
        public virtual ISearchResults Search(string scope, ISearchCriteria criteria)
        {
            var command = new SearchCommand(scope, criteria.DocumentType);

            command.Size(criteria.RecordsToRetrieve);
            command.From(criteria.StartingRecord);

            // Add spell checking
            // TODO: options.SpellCheck = new SpellCheckingParameters { Collate = true };

            // Build query
            var builder = (QueryBuilder<ESDocument>)_queryBuilder.BuildQuery(criteria);

            SearchResult<ESDocument> resultDocs;

            // Add some error handling
            try
            {
                resultDocs = Client.Search(command, builder);
            }
            catch (Exception ex)
            {
                throw new ElasticSearchException("Search using Elastic Search server failed, check logs for more details.", ex);
            }

            // Parse documents returned
            var documents = new ResultDocumentSet { TotalCount = resultDocs.hits.total };
            var docList = new List<ResultDocument>();
            foreach (var indexDoc in resultDocs.Documents)
            {
                var document = new ResultDocument();
                foreach (var field in indexDoc.Keys)
                    document.Add(new DocumentField(field, indexDoc[field]));

                docList.Add(document);
            }

            documents.Documents = docList.ToArray();

            // Create search results object
            var results = new SearchResults(criteria, new[] { documents });

            // Now add facet results
            var groups = new List<FacetGroup>();

            if (resultDocs.facets != null)
            {
                foreach (var filter in criteria.Filters)
                {
                    var groupCount = 0;

                    var group = new FacetGroup(filter.Key);

                    if (filter is AttributeFilter)
                    {
                        group.FacetType = FacetTypes.Attribute;
                        var attributeFilter = filter as AttributeFilter;
                        var myFilter = attributeFilter;
                        var values = myFilter.Values;
                        if (values != null)
                        {
                            var key = filter.Key.ToLower();
                            if (!resultDocs.facets.ContainsKey(key))
                                continue;

                            var facet = resultDocs.facets[key] as TermsFacetResult;
                            if (facet != null)
                            {
                                foreach (var value in values)
                                {
                                    //facet.terms
                                    var termCount = from f in facet.terms where f.term.Equals(value.Id, StringComparison.OrdinalIgnoreCase) select f.count;

                                    var enumerable = termCount as int[] ?? termCount.ToArray();
                                    if (!enumerable.Any())
                                        continue;

                                    //var facet = from resultFacet
                                    var newFacet = new Facet(@group, value.Id, GetDescription(value, criteria.Locale), enumerable.SingleOrDefault());
                                    @group.Facets.Add(newFacet);
                                }

                                groupCount++;
                            }
                        }
                    }
                    else if (filter is PriceRangeFilter)
                    {
                        group.FacetType = FacetTypes.PriceRange;
                        var rangeFilter = filter as PriceRangeFilter;
                        if (rangeFilter != null
                            && rangeFilter.Currency.Equals(criteria.Currency, StringComparison.OrdinalIgnoreCase))
                        {
                            var myFilter = rangeFilter;
                            var values = myFilter.Values;
                            if (values != null)
                            {
                                values = rangeFilter.Values;

                                foreach (var value in values)
                                {
                                    var key = String.Format("{0}-{1}", myFilter.Key, value.Id).ToLower();

                                    if (!resultDocs.facets.ContainsKey(key))
                                        continue;

                                    var facet = resultDocs.facets[key] as FilterFacetResult;

                                    if (facet != null && facet.count > 0)
                                    {
                                        if (facet.count == 0)
                                            continue;

                                        var myFacet = new Facet(
                                            @group, value.Id, GetDescription(value, criteria.Locale), facet.count);
                                        @group.Facets.Add(myFacet);

                                        groupCount++;
                                    }
                                }
                            }
                        }
                    }
                    else if (filter is RangeFilter)
                    {
                        group.FacetType = FacetTypes.Range;
                        var myFilter = filter as RangeFilter;
                        if (myFilter != null)
                        {
                            var values = myFilter.Values;
                            if (values != null)
                            {
                                foreach (var value in values)
                                {
                                    var facet = resultDocs.facets[filter.Key] as FilterFacetResult;

                                    if (facet == null || facet.count <= 0)
                                    {
                                        continue;
                                    }

                                    var myFacet = new Facet(
                                        @group, value.Id, GetDescription(value, criteria.Locale), facet.count);
                                    @group.Facets.Add(myFacet);

                                    groupCount++;
                                }
                            }
                        }
                    }
                    else if (filter is CategoryFilter)
                    {
                        group.FacetType = FacetTypes.Category;
                        var myFilter = filter as CategoryFilter;
                        if (myFilter != null)
                        {
                            var values = myFilter.Values;
                            if (values != null)
                            {
                                foreach (var value in values)
                                {
                                    var key = String.Format("{0}-{1}", myFilter.Key.ToLower(), value.Id.ToLower()).ToLower();
                                    var facet = resultDocs.facets[key] as FilterFacetResult;

                                    if (facet == null || facet.count <= 0)
                                    {
                                        continue;
                                    }

                                    var myFacet = new Facet(
                                        @group, value.Id, GetDescription(value, criteria.Locale), facet.count);
                                    @group.Facets.Add(myFacet);

                                    groupCount++;
                                }
                            }
                        }
                    }

                    // Add only if items exist under
                    if (groupCount > 0)
                    {
                        groups.Add(group);
                    }
                }
            }

            results.FacetGroups = groups.ToArray();
            return results;
        }
        private static FacetGroup[] CreateFacets(ISearchCriteria criteria, SearchResult<ESDocument>.SearchFacets facets)
        {
            var result = new List<FacetGroup>();

            if (facets != null)
            {
                foreach (var filter in criteria.Filters)
                {
                    var groupLabels = filter.GetLabels();
                    var facetGroup = new FacetGroup(filter.Key, groupLabels);

                    var values = filter.GetValues();

                    // Return all facet terms for attribute filter if values are not defined
                    if (values == null && filter is AttributeFilter)
                    {
                        facetGroup.FacetType = FacetTypes.Attribute;

                        var key = filter.Key.ToLower();
                        if (facets.ContainsKey(key))
                        {
                            var facet = facets[key] as TermsFacetResult;
                            if (facet != null)
                            {
                                foreach (var term in facet.terms)
                                {
                                    var newFacet = new Facet(facetGroup, term.term, term.count, null);
                                    facetGroup.Facets.Add(newFacet);
                                }
                            }
                        }
                    }

                    if (values != null)
                    {
                        foreach (var group in values.GroupBy(v => v.Id))
                        {
                            var valueLabels = group.GetValueLabels();

                            if (filter is AttributeFilter)
                            {
                                facetGroup.FacetType = FacetTypes.Attribute;

                                var key = filter.Key.ToLower();
                                if (facets.ContainsKey(key))
                                {
                                    var facet = facets[key] as TermsFacetResult;
                                    if (facet != null)
                                    {
                                        var term = facet.terms.FirstOrDefault(t => t.term.Equals(group.Key, StringComparison.OrdinalIgnoreCase));
                                        if (term != null)
                                        {
                                            var newFacet = new Facet(facetGroup, group.Key, term.count, valueLabels);
                                            facetGroup.Facets.Add(newFacet);
                                        }
                                    }
                                }
                            }
                            else if (filter is PriceRangeFilter)
                            {
                                facetGroup.FacetType = FacetTypes.PriceRange;

                                var rangeFilter = filter as PriceRangeFilter;
                                if (rangeFilter.Currency.Equals(criteria.Currency, StringComparison.OrdinalIgnoreCase))
                                {
                                    var key = string.Format(CultureInfo.InvariantCulture, "{0}-{1}", filter.Key, group.Key).ToLower();
                                    if (facets.ContainsKey(key))
                                    {
                                        var facet = facets[key] as FilterFacetResult;
                                        if (facet != null && facet.count > 0)
                                        {
                                            var newFacet = new Facet(facetGroup, group.Key, facet.count, valueLabels);
                                            facetGroup.Facets.Add(newFacet);
                                        }
                                    }
                                }
                            }
                            else if (filter is RangeFilter)
                            {
                                facetGroup.FacetType = FacetTypes.Range;

                                var key = filter.Key.ToLower();
                                if (facets.ContainsKey(key))
                                {
                                    var facet = facets[key] as FilterFacetResult;
                                    if (facet != null && facet.count > 0)
                                    {

                                        var newFacet = new Facet(facetGroup, group.Key, facet.count, valueLabels);
                                        facetGroup.Facets.Add(newFacet);
                                    }
                                }
                            }
                            else if (filter is CategoryFilter)
                            {
                                facetGroup.FacetType = FacetTypes.Category;

                                var key = string.Format(CultureInfo.InvariantCulture, "{0}-{1}", filter.Key, group.Key).ToLower();
                                if (facets.ContainsKey(key))
                                {
                                    var facet = facets[key] as FilterFacetResult;
                                    if (facet != null && facet.count > 0)
                                    {
                                        var newFacet = new Facet(facetGroup, group.Key, facet.count, valueLabels);
                                        facetGroup.Facets.Add(newFacet);
                                    }
                                }
                            }
                        }
                    }

                    // Add facet group only if has items
                    if (facetGroup.Facets.Any())
                    {
                        result.Add(facetGroup);
                    }
                }
            }

            return result.ToArray();
        }
Beispiel #33
0
        public ActionResult ProviderModelQuery(string keyWord)
        {
            // Create criteria
            CatalogEntrySearchCriteria criteria = new CatalogEntrySearchCriteria
            {
                RecordsToRetrieve = 200, // there is a default of 50
                // Locale have to be there... else no hits
                Locale       = ContentLanguage.PreferredCulture.TwoLetterISOLanguageName,
                SearchPhrase = keyWord
            };

            // Add more to the criteria
            criteria.Sort = CatalogEntrySearchCriteria.DefaultSortOrder;
            criteria.CatalogNames.Add("Fashion"); // ...if we know what catalog to search in, not mandatory
            //criteria.IgnoreFilterOnLanguage = true; // if we want to search all languages... need the locale anyway

            criteria.ClassTypes.Add(EntryType.Variation);
            criteria.MarketId = MarketId.Default; // should use the ICurrentMarket service, of course...

            criteria.IsFuzzySearch      = true;
            criteria.FuzzyMinSimilarity = 0.7F;

            criteria.IncludeInactive = true;

            // the _outline field
            System.Collections.Specialized.StringCollection sc =
                new System.Collections.Specialized.StringCollection
            {
                "Fashion/Clothes_1/Men_1/Shirts_1",
                "Fashion/Clothes_1/UniSex_1"
            };
            criteria.Outlines = sc; // another "AND"

            #region SimpleWalues
            ///*
            // Add facets to the criteria... and later prepare them for the "search result" as FacetGroups
            // With the below only these values are in the result... no Red or RollsRoys
            Mediachase.Search.SimpleValue svWhite = new SimpleValue
            {
                value        = "white",
                key          = "white",
                locale       = "en",
                Descriptions = new Descriptions {
                    defaultLocale = "en"
                }
            };
            var descWhite = new Description
            {
                locale = "en",
                Value  = "White"
            };
            svWhite.Descriptions.Description = new[] { descWhite };

            // If added like this it ends up in "ActiveFields" of the criteria and the result is filtered
            //criteria.Add("color", svWhite);
            // ...also the facetGroups on the "result" are influenced

            Mediachase.Search.SimpleValue svBlue = new SimpleValue
            {
                value        = "blue",
                key          = "blue",
                locale       = "en",
                Descriptions = new Descriptions {
                    defaultLocale = "en"
                }
            };
            var descBlue = new Description
            {
                locale = "en",
                Value  = "Blue"
            };
            svBlue.Descriptions.Description = new[] { descBlue };
            //criteria.Add("color", svBlue);

            Mediachase.Search.SimpleValue svVolvo = new SimpleValue
            {
                value        = "volvo",
                key          = "volvo",
                locale       = "en",
                Descriptions = new Descriptions {
                    defaultLocale = "en"
                }
            };
            var descVolvo = new Description
            {
                locale = "en",
                Value  = "volvo"
            };
            svVolvo.Descriptions.Description = new[] { descVolvo };
            //criteria.Add("brand", svVolvo);

            Mediachase.Search.SimpleValue svSaab = new SimpleValue
            {
                value        = "saab",
                key          = "saab",
                locale       = "en",
                Descriptions = new Descriptions {
                    defaultLocale = "en"
                }
            };
            var descSaab = new Description
            {
                locale = "en",
                Value  = "saab"
            };
            svSaab.Descriptions.Description = new[] { descSaab };
            //criteria.Add("brand", svSaab);

            #region Debug

            // the above filters the result so only saab (the blue) is there
            // With the above only we see only the Blue shirt... is that a saab - yes
            // New: no xml --> gives one Active and an empty filter even searchFilter.Values.SimpleValue below is there
            // New: outcommenting the above line --> and add XML file ... no "Active Fileds"
            // Have the Filters added - but no actice fields
            // New: trying this... Brand gets "ActiveField" with volvo & saab.. but the result shows all brands
            // New: outcommenting the below line and adding above only one, the saab
            //criteria.Add("brand", new List<ISearchFilterValue> { svSaab, svVolvo });
            // ...get a FacetGroups "in there"... like with the XML-file ... a manual way to add...
            // ...stuff that is not in the XML-file, or skip the XML File
            // New: taking out the single saab filter added

            #endregion

            SearchFilter searchFilterColor = new SearchFilter
            {
                //field = BaseCatalogIndexBuilder.FieldConstants.Catalog, // Have a bunch
                field = "color",

                // mandatory
                Descriptions = new Descriptions
                {
                    // another way of getting the language
                    defaultLocale = _langResolver.Service.GetPreferredCulture().Name
                },

                Values = new SearchFilterValues(),
            };

            SearchFilter searchFilterBrand = new SearchFilter
            {
                field = "brand",

                Descriptions = new Descriptions
                {
                    defaultLocale = _langResolver.Service.GetPreferredCulture().Name
                },

                Values = new SearchFilterValues(),
            };

            var descriptionColor = new Description
            {
                locale = "en",
                Value  = "Color"
            };

            var descriptionBrand = new Description
            {
                locale = "en",
                Value  = "Brand"
            };


            searchFilterColor.Descriptions.Description = new[] { descriptionColor };
            searchFilterBrand.Descriptions.Description = new[] { descriptionBrand };

            searchFilterColor.Values.SimpleValue = new SimpleValue[] { svWhite, svBlue };
            searchFilterBrand.Values.SimpleValue = new SimpleValue[] { svVolvo, svSaab };

            // can do like the below or us the loop further down...
            // the "foreach (SearchFilter item in _NewSearchConfig.SearchFilters)"
            // use these in the second part of the demo... "without XML" ... saw that with XML-style
            criteria.Add(searchFilterColor);
            criteria.Add(searchFilterBrand);

            #region Debug

            // gets the "filters" without this below and the XML... further checks...
            // do we need this? ... seems not... or it doesn't work like this
            // New: Have XML and commenting out the below lines Looks the same as with it
            // New: second...outcommenting the criteria.Add(searchFilter);
            // the Facets prop is empty......without the XML
            // the below line seems not to work
            // New: adding these again together with the saab above active
            //... difference is the "VariationFilter"
            // We get the Facets on the criteria, but no facets in the "result" without the XML

            //criteria.Filters = searchFilter; // read-only

            // Without the XML...

            // boom... on a missing "key"... the description
            // when commenting out the criteria.Add() for the simple values...??
            // When adding more to the SearchFilter it works...
            // ... the Simple values are there in the only instance if the filter
            // commenting out and check with the XML
            // when using the XML the groups sit in FacetGroups
            // when using the above... no facet-groups added

            // The same facets added a second time, Filter number 2 and no facet-groups
            //SearchConfig sConf = new SearchConfig();

            #endregion Debug

            //*/
            #endregion SimpleValues

            // use the manager for search and for index management
            SearchManager manager = new SearchManager("ECApplication");

            #region Facets/Filters

            // Filters from the XML file, populates the FacetGroups on the Search result
            string _SearchConfigPath =
                @"C:\Episerver612\CommerceTraining\CommerceTraining\Configs\Mediachase.Search.Filters.config";

            TextReader    reader     = new StreamReader(_SearchConfigPath);
            XmlSerializer serializer = new XmlSerializer((typeof(SearchConfig)));
            _SearchConfig = (SearchConfig)serializer.Deserialize(reader);
            reader.Close();

            foreach (SearchFilter filter in _SearchConfig.SearchFilters)
            {
                // Step 1 - use the XML file
                //criteria.Add(filter);
            }

            // Manual...
            SearchConfig _NewSearchConfig = new SearchConfig
            {
                SearchFilters = new SearchFilter[] { searchFilterColor, searchFilterBrand }
            };

            // can do like this, but there is another way (a bit above)
            foreach (SearchFilter item in _NewSearchConfig.SearchFilters)
            {
                // Step 2 - skip the XML file
                //criteria.Add(item);
            }

            #endregion

            // Do search
            ISearchResults results = manager.Search(criteria);

            #region Debug


            // doens't work
            //FacetGroup facetGroup = new FacetGroup("Bogus", "Bummer");
            //results.FacetGroups = new[] { facetGroup };

            // ...different return types - same method
            //SearchFilterHelper.Current.SearchEntries()

            // out comment and do a new try
            //ISearchFacetGroup[] facets = results.FacetGroups;

            // NEW: adding these ... for the provider, last line doesn's assign
            //ISearchFacetGroup[] searchFacetGroup0 = new SearchFacetGroup() { };
            FacetGroup facetGroup0 = new FacetGroup("colorgroup", "dummy"); //{ "",""}; // FacetGroup("brand","volvo");
            Facet      f1          = new Facet(facetGroup0, svWhite.key, svWhite.value, 1);
            facetGroup0.Facets.Add(f1);
            //facets[1] = facetGroup0;
            ISearchFacetGroup[] searchFacetGroup = new FacetGroup[] { facetGroup0 };
            //searchFacetGroup.Facets.Add(f1);
            //results.FacetGroups = searchFacetGroup; // nothing happens here, facet-group still empty

            #endregion

            int[] ints = results.GetKeyFieldValues <int>();

            // The DTO-way
            CatalogEntryDto dto = _catalogSystem.GetCatalogEntriesDto(ints);

            // CMS style (better)... using ReferenceConverter and ContentLoader
            List <ContentReference> refs = new List <ContentReference>();
            ints.ToList().ForEach(i => refs.Add(_referenceConverter.GetContentLink(i, CatalogContentType.CatalogEntry, 0)));

            localContent = _contentLoader.GetItems(refs, new LoaderOptions()); //

            // ToDo: Facets
            List <string> facetList = new List <string>();

            int facetGroups = results.FacetGroups.Count();

            foreach (ISearchFacetGroup item in results.FacetGroups)
            {
                foreach (var item2 in item.Facets)
                {
                    facetList.Add(String.Format("{0} {1} ({2})", item.Name, item2.Name, item2.Count));
                }
            }

            var searchResultViewModel = new SearchResultViewModel
            {
                totalHits = new List <string> {
                    ""
                },                                   // change
                nodes      = localContent.OfType <FashionNode>(),
                products   = localContent.OfType <ShirtProduct>(),
                variants   = localContent.OfType <ShirtVariation>(),
                allContent = localContent,
                facets     = facetList
            };


            return(View(searchResultViewModel));
        }
        /// <summary>
        /// Creates facets.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="query">The query.</param>
        private void CreateFacets(IndexReader reader, Query query)
        {
            var groups = new List<FacetGroup>();

            if (this.Results.SearchCriteria.Filters != null && this.Results.SearchCriteria.Filters.Length > 0)
            {
                var baseQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(query));

                var baseBitArray = baseQueryFilter.GetDocIdSet(reader);
                foreach (var filter in this.Results.SearchCriteria.Filters)
                {
                    var group = new FacetGroup(filter.Key);

                    var groupCount = 0;

                    if (!String.IsNullOrEmpty(this.Results.SearchCriteria.Currency) && filter is s.PriceRangeFilter)
                    {
                        var valCurrency = ((s.PriceRangeFilter)filter).Currency;
                        if (
                            !valCurrency.Equals(
                                this.Results.SearchCriteria.Currency, StringComparison.OrdinalIgnoreCase))
                        {
                            continue;
                        }
                    }

                    groupCount += this.CalculateResultCount(
                        reader, baseBitArray, group, filter, this.Results.SearchCriteria.Currency);

                    // Add only if items exist under
                    if (groupCount > 0)
                    {
                        groups.Add(group);
                    }
                }
            }

            this.Results.FacetGroups = groups.ToArray();
        }
 public ActionResult FacetGroup(FacetGroup facetGroup, string templateName)
 {
     // Just a "proxy" for our "DefaultFacetTemplateSelector"
     return(PartialView(templateName, facetGroup));
 }
        /// <summary>
        /// Calculates the result count.
        /// </summary>
        /// <param name="reader">The reader.</param>
        /// <param name="baseDocIdSet">The base doc id set.</param>
        /// <param name="facetGroup">The facet group.</param>
        /// <param name="filter">The filter.</param>
        /// <param name="currency">The currency.</param>
        /// <returns></returns>
        private int CalculateResultCount(
            IndexReader reader, DocIdSet baseDocIdSet, FacetGroup facetGroup, ISearchFilter filter, string currency)
        {
            var count = 0;

            ISearchFilterValue[] values = null;
            var priceQuery = false;
            if (filter is s.AttributeFilter)
            {
                values = ((s.AttributeFilter)filter).Values;
            }
            else if (filter is s.RangeFilter)
            {
                values = ((s.RangeFilter)filter).Values;
            }
            else if (filter is s.PriceRangeFilter)
            {
                values = ((s.PriceRangeFilter)filter).Values;
                priceQuery = true;
            }

            if (values == null)
            {
                return 0;
            }

            foreach (var value in values)
            {
                Query q = null;
                if (priceQuery)
                {
                    q = LuceneQueryHelper.CreateQuery(
                        this.Results.SearchCriteria, filter.Key, value as s.RangeFilterValue);
                }
                else
                {
                    q = LuceneQueryHelper.CreateQuery(filter.Key, value);
                }

                if (q == null) continue;

                var queryFilter = new CachingWrapperFilter(new QueryWrapperFilter(q));
                var filterArray = queryFilter.GetDocIdSet(reader);
                var newCount = (int)this.CalculateFacetCount(baseDocIdSet, filterArray);
                if (newCount == 0) continue;

                var newFacet = new Facet(facetGroup, value.Id, this.GetDescription(value, this.Results.SearchCriteria.Locale), newCount);
                facetGroup.Facets.Add(newFacet);
                count += newCount;
            }

            return count;
        }
Beispiel #37
0
        protected virtual IDictionary <string, FacetGroup> GetFacets(ForumSearchQuery searchQuery, int totalHits)
        {
            var result     = new Dictionary <string, FacetGroup>();
            var storeId    = searchQuery.StoreId ?? _services.StoreContext.CurrentStore.Id;
            var languageId = searchQuery.LanguageId ?? _services.WorkContext.WorkingLanguage.Id;

            foreach (var key in searchQuery.FacetDescriptors.Keys)
            {
                var descriptor = searchQuery.FacetDescriptors[key];
                var facets     = new List <Facet>();
                var kind       = FacetGroup.GetKindByKey("Forum", key);

                if (kind == FacetGroupKind.Forum)
                {
                    var enoughFacets = false;
                    var groups       = _forumService.GetAllForumGroups(storeId);

                    foreach (var group in groups)
                    {
                        foreach (var forum in group.Forums)
                        {
                            facets.Add(new Facet(new FacetValue(forum.Id, IndexTypeCode.Int32)
                            {
                                IsSelected   = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(forum.Id)),
                                Label        = forum.GetLocalized(x => x.Name, languageId),
                                DisplayOrder = forum.DisplayOrder
                            }));

                            if (descriptor.MaxChoicesCount > 0 && facets.Count >= descriptor.MaxChoicesCount)
                            {
                                enoughFacets = true;
                                break;
                            }
                        }

                        if (enoughFacets)
                        {
                            break;
                        }
                    }
                }
                else if (kind == FacetGroupKind.Customer)
                {
                    // Get customers with most posts.
                    var customerQuery = FacetUtility.GetCustomersByNumberOfPosts(
                        _forumPostRepository,
                        _storeMappingRepository,
                        QuerySettings.IgnoreMultiStore ? 0 : storeId,
                        descriptor.MinHitCount);

                    // Limit the result. Do not allow to get all customers.
                    var maxChoices = descriptor.MaxChoicesCount > 0 ? descriptor.MaxChoicesCount : 20;
                    var take       = maxChoices * 3;
                    var customers  = customerQuery.Take(() => take).ToList();

                    foreach (var customer in customers)
                    {
                        var name = customer.FormatUserName(_customerSettings, T, true);
                        if (name.HasValue())
                        {
                            facets.Add(new Facet(new FacetValue(customer.Id, IndexTypeCode.Int32)
                            {
                                IsSelected   = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(customer.Id)),
                                Label        = name,
                                DisplayOrder = 0
                            }));
                            if (facets.Count >= maxChoices)
                            {
                                break;
                            }
                        }
                    }
                }
                else if (kind == FacetGroupKind.Date)
                {
                    foreach (var value in descriptor.Values)
                    {
                        facets.Add(new Facet(value));
                    }
                }

                if (facets.Any(x => x.Published))
                {
                    //facets.Each(x => $"{key} {x.Value.ToString()}".Dump());

                    var group = new FacetGroup(
                        "Forum",
                        key,
                        descriptor.Label,
                        descriptor.IsMultiSelect,
                        false,
                        descriptor.DisplayOrder,
                        facets.OrderBy(descriptor))
                    {
                        IsScrollable = facets.Count > 14
                    };

                    result.Add(key, group);
                }
            }

            return(result);
        }
        protected virtual IDictionary <string, FacetGroup> GetFacets(CatalogSearchQuery searchQuery, int totalHits)
        {
            var result     = new Dictionary <string, FacetGroup>();
            var storeId    = searchQuery.StoreId ?? _services.StoreContext.CurrentStore.Id;
            var languageId = searchQuery.LanguageId ?? _services.WorkContext.WorkingLanguage.Id;

            foreach (var key in searchQuery.FacetDescriptors.Keys)
            {
                var descriptor = searchQuery.FacetDescriptors[key];
                var facets     = new List <Facet>();
                var kind       = FacetGroup.GetKindByKey("Catalog", key);

                switch (kind)
                {
                case FacetGroupKind.Category:
                case FacetGroupKind.Brand:
                case FacetGroupKind.DeliveryTime:
                case FacetGroupKind.Rating:
                case FacetGroupKind.Price:
                    if (totalHits == 0 && !descriptor.Values.Any(x => x.IsSelected))
                    {
                        continue;
                    }
                    break;
                }

                if (kind == FacetGroupKind.Category)
                {
                    var categoryTree = _categoryService.GetCategoryTree(0, false, storeId);
                    var categories   = categoryTree.Flatten(false);

                    if (descriptor.MaxChoicesCount > 0)
                    {
                        categories = categories.Take(descriptor.MaxChoicesCount);
                    }

                    var nameQuery = _localizedPropertyRepository.TableUntracked
                                    .Where(x => x.LocaleKeyGroup == "Category" && x.LocaleKey == "Name" && x.LanguageId == languageId);
                    var names = nameQuery.ToList().ToDictionarySafe(x => x.EntityId, x => x.LocaleValue);

                    foreach (var category in categories)
                    {
                        names.TryGetValue(category.Id, out var label);

                        facets.Add(new Facet(new FacetValue(category.Id, IndexTypeCode.Int32)
                        {
                            IsSelected   = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(category.Id)),
                            Label        = label.HasValue() ? label : category.Name,
                            DisplayOrder = category.DisplayOrder
                        }));
                    }
                }
                else if (kind == FacetGroupKind.Brand)
                {
                    var manufacturers = _manufacturerService.GetAllManufacturers(null, storeId);
                    if (descriptor.MaxChoicesCount > 0)
                    {
                        manufacturers = manufacturers.Take(descriptor.MaxChoicesCount).ToList();
                    }

                    var nameQuery = _localizedPropertyRepository.TableUntracked
                                    .Where(x => x.LocaleKeyGroup == "Manufacturer" && x.LocaleKey == "Name" && x.LanguageId == languageId);
                    var names = nameQuery.ToList().ToDictionarySafe(x => x.EntityId, x => x.LocaleValue);

                    foreach (var manu in manufacturers)
                    {
                        names.TryGetValue(manu.Id, out var label);

                        facets.Add(new Facet(new FacetValue(manu.Id, IndexTypeCode.Int32)
                        {
                            IsSelected   = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(manu.Id)),
                            Label        = label.HasValue() ? label : manu.Name,
                            DisplayOrder = manu.DisplayOrder
                        }));
                    }
                }
                else if (kind == FacetGroupKind.DeliveryTime)
                {
                    var deliveryTimes = _deliveryTimeService.GetAllDeliveryTimes();
                    var nameQuery     = _localizedPropertyRepository.TableUntracked
                                        .Where(x => x.LocaleKeyGroup == "DeliveryTime" && x.LocaleKey == "Name" && x.LanguageId == languageId);
                    var names = nameQuery.ToList().ToDictionarySafe(x => x.EntityId, x => x.LocaleValue);

                    foreach (var deliveryTime in deliveryTimes)
                    {
                        if (descriptor.MaxChoicesCount > 0 && facets.Count >= descriptor.MaxChoicesCount)
                        {
                            break;
                        }

                        names.TryGetValue(deliveryTime.Id, out var label);

                        facets.Add(new Facet(new FacetValue(deliveryTime.Id, IndexTypeCode.Int32)
                        {
                            IsSelected   = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(deliveryTime.Id)),
                            Label        = label.HasValue() ? label : deliveryTime.Name,
                            DisplayOrder = deliveryTime.DisplayOrder
                        }));
                    }
                }
                else if (kind == FacetGroupKind.Price)
                {
                    var count = 0;
                    var hasActivePredefinedFacet = false;
                    var minPrice = _productRepository.Table.Where(x => x.Published && !x.Deleted && !x.IsSystemProduct).Min(x => (double)x.Price);
                    var maxPrice = _productRepository.Table.Where(x => x.Published && !x.Deleted && !x.IsSystemProduct).Max(x => (double)x.Price);
                    minPrice = FacetUtility.MakePriceEven(minPrice);
                    maxPrice = FacetUtility.MakePriceEven(maxPrice);

                    for (var i = 0; i < _priceThresholds.Length; ++i)
                    {
                        if (descriptor.MaxChoicesCount > 0 && facets.Count >= descriptor.MaxChoicesCount)
                        {
                            break;
                        }

                        var price = _priceThresholds[i];
                        if (price < minPrice)
                        {
                            continue;
                        }

                        if (price >= maxPrice)
                        {
                            i = int.MaxValue - 1;
                        }

                        var selected = descriptor.Values.Any(x => x.IsSelected && x.Value == null && x.UpperValue != null && (double)x.UpperValue == price);
                        if (selected)
                        {
                            hasActivePredefinedFacet = true;
                        }

                        facets.Add(new Facet(new FacetValue(null, price, IndexTypeCode.Double, false, true)
                        {
                            DisplayOrder = ++count,
                            IsSelected   = selected
                        }));
                    }

                    // Add facet for custom price range.
                    var priceDescriptorValue = descriptor.Values.FirstOrDefault();

                    var customPriceFacetValue = new FacetValue(
                        priceDescriptorValue != null && !hasActivePredefinedFacet ? priceDescriptorValue.Value : null,
                        priceDescriptorValue != null && !hasActivePredefinedFacet ? priceDescriptorValue.UpperValue : null,
                        IndexTypeCode.Double,
                        true,
                        true);

                    customPriceFacetValue.IsSelected = customPriceFacetValue.Value != null || customPriceFacetValue.UpperValue != null;

                    if (!(totalHits == 0 && !customPriceFacetValue.IsSelected))
                    {
                        facets.Insert(0, new Facet("custom", customPriceFacetValue));
                    }
                }
                else if (kind == FacetGroupKind.Rating)
                {
                    foreach (var rating in FacetUtility.GetRatings())
                    {
                        var newFacet = new Facet(rating);
                        newFacet.Value.IsSelected = descriptor.Values.Any(x => x.IsSelected && x.Value.Equals(rating.Value));
                        facets.Add(newFacet);
                    }
                }
                else if (kind == FacetGroupKind.Availability || kind == FacetGroupKind.NewArrivals)
                {
                    var value = descriptor.Values.FirstOrDefault();
                    if (value != null)
                    {
                        if (kind == FacetGroupKind.NewArrivals && totalHits == 0 && !value.IsSelected)
                        {
                            continue;
                        }

                        var newValue = value.Clone();
                        newValue.Value      = true;
                        newValue.TypeCode   = IndexTypeCode.Boolean;
                        newValue.IsRange    = false;
                        newValue.IsSelected = value.IsSelected;

                        facets.Add(new Facet(newValue));
                    }
                }

                if (facets.Any(x => x.Published))
                {
                    //facets.Each(x => $"{key} {x.Value.ToString()}".Dump());

                    result.Add(key, new FacetGroup(
                                   "Catalog",
                                   key,
                                   descriptor.Label,
                                   descriptor.IsMultiSelect,
                                   false,
                                   descriptor.DisplayOrder,
                                   facets.OrderBy(descriptor)));
                }
            }

            return(result);
        }
Beispiel #39
0
        public IEnumerable <IHit> Query(int pageIndex, int pageSize, out int totalCount, out IEnumerable <FacetGroup> facetedResults)
        {
            totalCount     = 0;
            facetedResults = null;

            if (searchPaths == null || searchPaths.Count <= 0)
            {
                searchPaths.AddRange(indexPaths.Values.Select(o => o.Path));
            }

            List <LuceneHit> results = new List <LuceneHit>();

            List <IndexSearcher> subSearchs = new List <IndexSearcher>();

            searchPaths.ForEach(o => subSearchs.Add(new IndexSearcher(FSDirectory.Open(o))));

            if (facetFields != null && facetFields.Count > 0)
            {
                var         facetGroups     = new List <FacetGroup>();
                var         mainQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(query));
                MultiReader readers         = new MultiReader(subSearchs.Select(o => o.IndexReader).ToArray());

                foreach (var facetField in facetFields)
                {
                    FacetGroup fg = new FacetGroup();
                    fg.FieldName = facetFieldNameProvider.GetMapName(TypeName, facetField);
                    var items = new List <FacetItem>();

                    var allDistinctField = FieldCache_Fields.DEFAULT.GetStrings(readers, facetField).Distinct().ToArray();
                    int totalHits        = 0;

                    Parallel.ForEach(allDistinctField, fieldValue =>
                    {
                        //foreach (var fieldValue in allDistinctField)
                        //{
                        var facetQuery       = new TermQuery(new Term(facetField, fieldValue));
                        var facetQueryFilter = new CachingWrapperFilter(new QueryWrapperFilter(facetQuery));

                        var bs = new OpenBitSetDISI(facetQueryFilter.GetDocIdSet(readers).Iterator(), readers.MaxDoc);
                        bs.InPlaceAnd(mainQueryFilter.GetDocIdSet(readers).Iterator());
                        int count = (Int32)bs.Cardinality();

                        FacetItem item  = new FacetItem();
                        item.GroupValue = fieldValue;
                        item.Count      = count;

                        items.Add(item);
                        totalHits += count;
                    }
                                     );

                    fg.FacetItems = items.OrderByDescending(o => o.Count);
                    fg.TotalHits  = totalHits;

                    facetGroups.Add(fg);
                }

                facetedResults = facetGroups.OrderBy(o => o.FieldName);
            }
            ParallelMultiSearcher searcher = new ParallelMultiSearcher(subSearchs.ToArray());
            Sort sort = null;

            if (sortFields != null && sortFields.Count > 0)
            {
                sort = new Sort(sortFields.ToArray());
            }

            int maxDoc     = searcher.MaxDoc;
            int startIndex = 0;

            if (pageIndex >= 0 && pageSize > 0)
            {
                startIndex = pageIndex * pageSize;
                maxDoc     = pageSize * (pageIndex + 1);
            }
            var docs = sort == null?searcher.Search(query, null, maxDoc) : searcher.Search(query, null, maxDoc, sort);

            totalCount = docs.TotalHits;
            int endIndex = docs.TotalHits - startIndex;

            for (int i = startIndex; i < endIndex; i++)
            {
                LuceneHit h = new LuceneHit(TypeName, DocumentBuilder, searcher.Doc(docs.ScoreDocs[i].Doc));
                results.Add(h);
            }
            return(results);
        }