Beispiel #1
0
        public virtual CategorySearchResult SearchCategories(string scope, ISearchCriteria criteria, CategoryResponseGroup responseGroup)
        {
            var items            = new List <Category>();
            var itemsOrderedList = new List <string>();

            var foundItemCount = 0;
            var dbItemCount    = 0;
            var searchRetry    = 0;

            //var myCriteria = criteria.Clone();
            var myCriteria = criteria;

            ISearchResults <DocumentDictionary> searchResults = null;

            do
            {
                // Search using criteria, it will only return IDs of the items
                searchResults = _searchProvider.Search <DocumentDictionary>(scope, criteria);

                searchRetry++;

                if (searchResults == null || searchResults.Documents == null)
                {
                    continue;
                }

                //Get only new found itemIds
                var uniqueKeys = searchResults.Documents.Select(x => x.Id.ToString()).Except(itemsOrderedList).ToArray();
                foundItemCount = uniqueKeys.Length;

                if (!searchResults.Documents.Any())
                {
                    continue;
                }

                itemsOrderedList.AddRange(uniqueKeys);

                // if we can determine catalog, pass it to the service
                string catalog = null;
                if (criteria is CatalogItemSearchCriteria)
                {
                    catalog = (criteria as CatalogItemSearchCriteria).Catalog;
                }

                // Now load items from repository
                var currentItems = _categoryService.GetByIds(uniqueKeys.ToArray(), responseGroup, catalog);

                var orderedList = currentItems.OrderBy(i => itemsOrderedList.IndexOf(i.Id));
                items.AddRange(orderedList);
                dbItemCount = currentItems.Length;

                //If some items where removed and search is out of sync try getting extra items
                if (foundItemCount > dbItemCount)
                {
                    //Retrieve more items to fill missing gap
                    myCriteria.RecordsToRetrieve += (foundItemCount - dbItemCount);
                }
            }while (foundItemCount > dbItemCount && searchResults != null && searchResults.Documents.Any() && searchRetry <= 3 &&
                    (myCriteria.RecordsToRetrieve + myCriteria.StartingRecord) < searchResults.TotalCount);

            var response = new CategorySearchResult();

            if (items != null)
            {
                var categoryDtos = new ConcurrentBag <CatalogModule.Web.Model.Category>();
                Parallel.ForEach(items, (x) =>
                {
                    categoryDtos.Add(x.ToWebModel(_blobUrlResolver));
                });
                response.Categories = categoryDtos.OrderBy(i => itemsOrderedList.IndexOf(i.Id)).ToArray();
            }

            if (searchResults != null)
            {
                response.TotalCount = searchResults.TotalCount;
            }

            return(response);
        }
Beispiel #2
0
        public virtual CategorySearchResult SearchCategories(string scope, ISearchCriteria criteria, CategoryResponseGroup responseGroup)
        {
            var response      = new CategorySearchResult();
            var searchResults = _searchProvider.Search <DocumentDictionary>(scope, criteria);

            if (searchResults?.Documents != null)
            {
                var categoryDtos = new ConcurrentBag <CatalogModule.Web.Model.Category>();
                var taskList     = new List <Task>();

                var documents = searchResults.Documents;
                if (_settingsManager.GetValue("VirtoCommerce.SearchApi.UseFullObjectIndexStoring", true))
                {
                    var fullIndexedDocuments = documents.Where(doc => doc.ContainsKey(IndexHelper.ObjectFieldName) && !string.IsNullOrEmpty(doc[IndexHelper.ObjectFieldName].ToString())).ToList();
                    documents = documents.Except(fullIndexedDocuments).ToList();

                    var deserializeProductsTask = Task.Factory.StartNew(() =>
                    {
                        Parallel.ForEach(fullIndexedDocuments, new ParallelOptions {
                            MaxDegreeOfParallelism = 5
                        }, doc =>
                        {
                            var category = doc.GetObjectFieldValue <CatalogModule.Web.Model.Category>();
                            categoryDtos.Add(category);
                        });
                    });
                    taskList.Add(deserializeProductsTask);
                }

                if (documents.Any())
                {
                    var loadProductsTask = Task.Factory.StartNew(() =>
                    {
                        string catalog = null;
                        var catalogItemSearchCriteria = criteria as CatalogItemSearchCriteria;
                        if (catalogItemSearchCriteria != null)
                        {
                            catalog = catalogItemSearchCriteria.Catalog;
                        }

                        var categoryIds = documents.Select(x => x.Id.ToString()).Distinct().ToArray();
                        if (categoryIds.Any())
                        {
                            // Now load items from repository
                            var categories = _categoryService.GetByIds(categoryIds, responseGroup, catalog);
                            Parallel.ForEach(categories, x =>
                            {
                                categoryDtos.Add(x.ToWebModel(_blobUrlResolver));
                            });
                        }
                    }
                                                                 );
                    taskList.Add(loadProductsTask);
                }

                Task.WaitAll(taskList.ToArray());

                //Preserver original sorting order
                var orderedIds = searchResults.Documents.Select(x => x.Id.ToString()).ToList();
                response.Categories = categoryDtos.OrderBy(i => orderedIds.IndexOf(i.Id)).ToArray();
            }


            if (searchResults != null)
            {
                response.TotalCount = searchResults.TotalCount;
            }

            return(response);
        }