Пример #1
0
        public async Task <CatalogSearchResult> SearchAsync(CatalogSearchQuery searchQuery, bool direct = false)
        {
            await _services.EventPublisher.PublishAsync(new CatalogSearchingEvent(searchQuery, true));

            var totalHits = 0;

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

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

                totalHits = await query.CountAsync();

                //totalHits = await query.Select(x => x.Id).Distinct().CountAsync();

                // 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;

                    //var query2 = query
                    //    .Select(x => x.Id)
                    //    .Distinct()
                    //    .Skip(skip)
                    //    .Take(searchQuery.Take);
                    //query2.ToQueryString().Dump();
                    //hitsEntityIds = query2.ToArray();

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

                    hitsEntityIds = query.Select(x => x.Id).ToArray();
                    hitsFactory   = async() => await _db.Products.GetManyAsync(hitsEntityIds);
                }

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

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

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

            return(searchedEvent.Result);
        }
Пример #2
0
        public async Task <CatalogSearchResult> SearchAsync(CatalogSearchQuery searchQuery, bool direct = false)
        {
            Guard.NotNull(searchQuery, nameof(searchQuery));
            Guard.NotNegative(searchQuery.Take, nameof(searchQuery.Take));

            var provider = _indexManager.GetIndexProvider(Scope);

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

                    int      totalCount              = 0;
                    int[]    hitsEntityIds           = null;
                    string[] spellCheckerSuggestions = null;
                    IEnumerable <ISearchHit>         searchHits;
                    IDictionary <string, FacetGroup> facets = null;

                    await _services.EventPublisher.PublishAsync(new CatalogSearchingEvent(searchQuery, false));

                    if (searchQuery.Take > 0)
                    {
                        using (_services.Chronometer.Step(stepPrefix + "Search"))
                        {
                            totalCount = await searchEngine.CountAsync();

                            // 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 = await searchEngine.SearchAsync();
                            }

                            hitsEntityIds = searchHits.Select(x => x.EntityId).ToArray();
                        }

                        if (searchQuery.ResultFlags.HasFlag(SearchResultFlags.WithFacets))
                        {
                            try
                            {
                                using (_services.Chronometer.Step(stepPrefix + "Facets"))
                                {
                                    facets = await searchEngine.GetFacetMapAsync();

                                    ApplyFacetLabels(facets);
                                }
                            }
                            catch (Exception ex)
                            {
                                Logger.Error(ex);
                            }
                        }
                    }

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

                    var result = new CatalogSearchResult(
                        searchEngine,
                        searchQuery,
                        _db.Products,
                        totalCount,
                        hitsEntityIds,
                        spellCheckerSuggestions,
                        facets);

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

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

            return(await SearchDirectAsync(searchQuery));
        }