public virtual IList <Product> GetProductsByIds(int[] productIds, ProductLoadFlags flags = ProductLoadFlags.None)
        {
            if (productIds == null || productIds.Length == 0)
            {
                return(new List <Product>());
            }

            var query = from p in _productRepository.Table
                        where productIds.Contains(p.Id)
                        select p;

            if (flags > ProductLoadFlags.None)
            {
                query = ApplyLoadFlags(query, flags);
            }

            var products = query.ToList();

            // sort by passed identifier sequence
            var sortQuery = from i in productIds
                            join p in products on i equals p.Id
                            select p;

            return(sortQuery.ToList());
        }
        public CatalogSearchResult Search(CatalogSearchQuery searchQuery, ProductLoadFlags loadFlags = ProductLoadFlags.None, bool direct = false)
        {
            _services.EventPublisher.Publish(new CatalogSearchingEvent(searchQuery, true));

            var totalHits = 0;

            int[] hitsEntityIds = null;
            Func <IList <Product> >          hitsFactory = null;
            IDictionary <string, FacetGroup> facets      = null;

            if (searchQuery.Take > 0)
            {
                var query = GetProductQuery(searchQuery, null);

                totalHits = query.Count();

                // Fix paging boundaries
                if (searchQuery.Skip > 0 && searchQuery.Skip >= totalHits)
                {
                    searchQuery.Slice((totalHits / searchQuery.Take) * searchQuery.Take, searchQuery.Take);
                }

                if (searchQuery.ResultFlags.HasFlag(SearchResultFlags.WithHits))
                {
                    var skip = searchQuery.PageIndex * searchQuery.Take;

                    query = query
                            .Skip(() => skip)
                            .Take(() => searchQuery.Take);

                    hitsEntityIds = query.Select(x => x.Id).ToArray();
                    hitsFactory   = () => _productService.GetProductsByIds(hitsEntityIds, loadFlags);
                }

                if (searchQuery.ResultFlags.HasFlag(SearchResultFlags.WithFacets) && searchQuery.FacetDescriptors.Any())
                {
                    facets = GetFacets(searchQuery, totalHits);
                }
            }

            var result = new CatalogSearchResult(
                null,
                searchQuery,
                totalHits,
                hitsEntityIds,
                hitsFactory,
                null,
                facets);

            _services.EventPublisher.Publish(new CatalogSearchedEvent(searchQuery, result));

            return(result);
        }
Exemple #3
0
        public CatalogSearchResult Search(CatalogSearchQuery searchQuery, ProductLoadFlags loadFlags = ProductLoadFlags.None, bool direct = false)
        {
            _eventPublisher.Publish(new CatalogSearchingEvent(searchQuery));

            var totalHits = 0;
            Func <IList <Product> >          hitsFactory = null;
            IDictionary <string, FacetGroup> facets      = null;

            if (searchQuery.Take > 0)
            {
                var query = GetProductQuery(searchQuery, null);

                totalHits = query.Count();

                if (searchQuery.ResultFlags.HasFlag(SearchResultFlags.WithHits))
                {
                    query = query
                            .Skip(searchQuery.PageIndex * searchQuery.Take)
                            .Take(searchQuery.Take);

                    var ids = query.Select(x => x.Id).ToArray();
                    hitsFactory = () => _productService.GetProductsByIds(ids, loadFlags);
                }

                if (searchQuery.ResultFlags.HasFlag(SearchResultFlags.WithFacets) && searchQuery.FacetDescriptors.Any())
                {
                    facets = GetFacets(searchQuery, totalHits);
                }
            }

            var result = new CatalogSearchResult(
                null,
                searchQuery,
                totalHits,
                hitsFactory,
                null,
                facets);

            _eventPublisher.Publish(new CatalogSearchedEvent(searchQuery, result));

            return(result);
        }
Exemple #4
0
        public virtual IList <Product> GetProductsByIds(int[] productIds, ProductLoadFlags flags = ProductLoadFlags.None)
        {
            if (productIds == null || !productIds.Any())
            {
                return(new List <Product>());
            }

            var query = from p in _productRepository.Table
                        where productIds.Contains(p.Id)
                        select p;

            if (flags > ProductLoadFlags.None)
            {
                query = ApplyLoadFlags(query, flags);
            }

            var products = query.ToList();

            // Sort by passed identifier sequence.
            return(products.OrderBySequence(productIds).ToList());
        }
        private IQueryable <Product> ApplyLoadFlags(IQueryable <Product> query, ProductLoadFlags flags)
        {
            if (flags.HasFlag(ProductLoadFlags.WithAttributeCombinations))
            {
                query = query.Include(x => x.ProductVariantAttributeCombinations);
            }

            if (flags.HasFlag(ProductLoadFlags.WithBundleItems))
            {
                query = query.Include(x => x.ProductBundleItems.Select(y => y.Product));
            }

            if (flags.HasFlag(ProductLoadFlags.WithCategories))
            {
                query = query.Include(x => x.ProductCategories.Select(y => y.Category));
            }

            if (flags.HasFlag(ProductLoadFlags.WithDiscounts))
            {
                query = query.Include(x => x.AppliedDiscounts);
            }

            if (flags.HasFlag(ProductLoadFlags.WithManufacturers))
            {
                query = query.Include(x => x.ProductManufacturers.Select(y => y.Manufacturer));
            }

            if (flags.HasFlag(ProductLoadFlags.WithPictures))
            {
                query = query.Include(x => x.ProductPictures);
            }

            if (flags.HasFlag(ProductLoadFlags.WithReviews))
            {
                query = query.Include(x => x.ProductReviews);
            }

            if (flags.HasFlag(ProductLoadFlags.WithSpecificationAttributes))
            {
                query = query.Include(x => x.ProductSpecificationAttributes.Select(y => y.SpecificationAttributeOption));
            }

            if (flags.HasFlag(ProductLoadFlags.WithTags))
            {
                query = query.Include(x => x.ProductTags);
            }

            if (flags.HasFlag(ProductLoadFlags.WithTierPrices))
            {
                query = query.Include(x => x.TierPrices);
            }

            if (flags.HasFlag(ProductLoadFlags.WithAttributes))
            {
                query = query.Include(x => x.ProductVariantAttributes.Select(y => y.ProductAttribute));
            }

            if (flags.HasFlag(ProductLoadFlags.WithAttributeValues))
            {
                query = query.Include(x => x.ProductVariantAttributes.Select(y => y.ProductVariantAttributeValues));
            }

            if (flags.HasFlag(ProductLoadFlags.WithDeliveryTime))
            {
                query = query.Include(x => x.DeliveryTime);
            }

            return(query);
        }
        /// <summary>
        /// Bypasses the index provider and directly searches in the database
        /// </summary>
        /// <param name="searchQuery">Search query</param>
        /// <param name="loadFlags">LOad flags</param>
        /// <returns>Catalog search result</returns>
        protected virtual CatalogSearchResult SearchDirect(CatalogSearchQuery searchQuery, ProductLoadFlags loadFlags = ProductLoadFlags.None)
        {
            // Fallback to linq search.
            var linqCatalogSearchService = _services.Container.ResolveNamed <ICatalogSearchService>("linq");

            var result = linqCatalogSearchService.Search(searchQuery, loadFlags, true);

            ApplyFacetLabels(result.Facets);

            return(result);
        }
        public CatalogSearchResult Search(
            CatalogSearchQuery searchQuery,
            ProductLoadFlags loadFlags = ProductLoadFlags.None,
            bool direct = false)
        {
            Guard.NotNull(searchQuery, nameof(searchQuery));
            Guard.NotNegative(searchQuery.Take, nameof(searchQuery.Take));

            var provider = _indexManager.GetIndexProvider("Catalog");

            if (!direct && provider != null)
            {
                var indexStore = provider.GetIndexStore("Catalog");
                if (indexStore.Exists)
                {
                    var searchEngine = provider.GetSearchEngine(indexStore, searchQuery);
                    var stepPrefix   = searchEngine.GetType().Name + " - ";

                    int      totalCount = 0;
                    string[] spellCheckerSuggestions = null;
                    IEnumerable <ISearchHit>         searchHits;
                    Func <IList <Product> >          hitsFactory = null;
                    IDictionary <string, FacetGroup> facets      = null;

                    _services.EventPublisher.Publish(new CatalogSearchingEvent(searchQuery, false));

                    if (searchQuery.Take > 0)
                    {
                        using (_services.Chronometer.Step(stepPrefix + "Search"))
                        {
                            totalCount = searchEngine.Count();
                            // Fix paging boundaries
                            if (searchQuery.Skip > 0 && searchQuery.Skip >= totalCount)
                            {
                                searchQuery.Slice((totalCount / searchQuery.Take) * searchQuery.Take, searchQuery.Take);
                            }
                        }

                        if (searchQuery.ResultFlags.HasFlag(SearchResultFlags.WithHits))
                        {
                            using (_services.Chronometer.Step(stepPrefix + "Hits"))
                            {
                                searchHits = searchEngine.Search();
                            }

                            using (_services.Chronometer.Step(stepPrefix + "Collect"))
                            {
                                var productIds = searchHits.Select(x => x.EntityId).ToArray();
                                hitsFactory = () => _productService.Value.GetProductsByIds(productIds, loadFlags);
                            }
                        }

                        if (searchQuery.ResultFlags.HasFlag(SearchResultFlags.WithFacets))
                        {
                            try
                            {
                                using (_services.Chronometer.Step(stepPrefix + "Facets"))
                                {
                                    facets = searchEngine.GetFacetMap();
                                    ApplyFacetLabels(facets);
                                }
                            }
                            catch (Exception ex)
                            {
                                _logger.Error(ex);
                            }
                        }
                    }

                    if (searchQuery.ResultFlags.HasFlag(SearchResultFlags.WithSuggestions))
                    {
                        try
                        {
                            using (_services.Chronometer.Step(stepPrefix + "Spellcheck"))
                            {
                                spellCheckerSuggestions = searchEngine.CheckSpelling();
                            }
                        }
                        catch (Exception ex)
                        {
                            // Spell checking should not break the search.
                            _logger.Error(ex);
                        }
                    }

                    var result = new CatalogSearchResult(
                        searchEngine,
                        searchQuery,
                        totalCount,
                        hitsFactory,
                        spellCheckerSuggestions,
                        facets);

                    var searchedEvent = new CatalogSearchedEvent(searchQuery, result);
                    _services.EventPublisher.Publish(searchedEvent);

                    return(searchedEvent.Result);
                }
                else if (searchQuery.Origin.IsCaseInsensitiveEqual("Search/Search"))
                {
                    IndexingRequiredNotification(_services, _urlHelper);
                }
            }

            return(SearchDirect(searchQuery));
        }