Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Simon 692 posts 1068 karma points
    Dec 06, 2016 @ 16:33
    Simon
    0

    Products Search by Collection is quite slow - Using Version 2.2.0

    Hi,

    At this point in time, I have a products listing where user can search by collections/categories.

    I am using Merchello Version 2.2.0 where it was not that easy to search by multiple collections.

    Below, you can find my logic how my search made up.

    But it is quite slow, it takes about 10 to 15 seconds to return results.

    At this point in time, which is at the final stage, I don't know if I can update to the latest and use some latest functions which can do this using Examine.

    But I am asking if it is possible if this could be manageable without upgrading everything since there might be some issues

    I would appreciate any solution for this guys.

    public ReturnedSearchedResultsModel Search(UmbracoHelper umbracoHelper,List<int> umbracoCategories, string searchText, int pageSize, int currentPage, string sortyByEnumValue)
                {
                    var merchelloHelper = new MerchelloHelper();
                    var returnedSearchedResultsModel = new ReturnedSearchedResultsModel();
    
                    //later on, we would need to get products according to track inventory
    
                    var returnedProducts = merchelloHelper.Query.Product.Search(1, int.MaxValue).Items.Select(x => (ProductDisplay)x);
    
                    if (umbracoCategories.Any())
                    {
                        //var listOfCategoriesGuids = _umbracoHelperService.TypedContent(umbracoHelper, ConstantValues.ProductsPageId).Children().Where(x => x.DocumentTypeAlias == ConstantValues.Document_Type_Alias_Product_Category && umbracoCategories.Contains(x.Id)).Select(x => (ProductCategory)x).Select(pc => pc.Products.CollectionKey);
    
                        var listOfCategoriesGuids = new List<Guid>();
                        foreach (var productCategoryId in umbracoCategories)
                        {
                            var productCategoryAsModel = new ProductCategory(_umbracoHelperService.TypedContent(umbracoHelper, productCategoryId));
    
                            if (productCategoryAsModel != null)
                            {
                                listOfCategoriesGuids.Add(productCategoryAsModel.Products.CollectionKey);
                            }
                        }
    
                        returnedProducts = merchelloHelper.Query.Product.Search(1, int.MaxValue).Items.Select(x => ((ProductDisplay)x).AsProductContent()).Where(x => x != null).Where(x => x.Collections().Select(p => p.CollectionKey).Intersect(listOfCategoriesGuids).Any()).Select(x => x.AsProductDisplay());
                    }
    
                    if (!String.IsNullOrEmpty(searchText))
                    {
                        returnedProducts = returnedProducts.Where(x => x.Name.ToLower().Contains(searchText.ToLower()));
                    }
    
                    //ordering
                    var orderedProducts = returnedProducts.OrderBy(x => x.Name);
                    var enumValueToEnum = EnumHelpers.ConvertStringToEnum(sortyByEnumValue, Enums.SearchSortyBy.NameAscending);
                    bool sortingSelected = false;
    
                    if (enumValueToEnum.Equals(Enums.SearchSortyBy.NameDescending))
                    {
                        sortingSelected = true;
                        orderedProducts = orderedProducts.OrderByDescending(x => x.Name).ThenBy(x => new Product(x.AsProductContent()).Ranking);
                    }
                    else if (enumValueToEnum.Equals(Enums.SearchSortyBy.Newest))
                    {
                        sortingSelected = true;
                        orderedProducts = orderedProducts.OrderByDescending(x => new Product(x.AsProductContent()).CreationDate).ThenBy(x => new Product(x.AsProductContent()).Ranking);
                    }
                    else if (enumValueToEnum.Equals(Enums.SearchSortyBy.NameAscending))
                    {
                        sortingSelected = true;
                        //order by name is already done, at the top
                    }
    
                    if (!sortingSelected)
                    {
                        orderedProducts = orderedProducts.OrderBy(x => new Product(x.AsProductContent()).Ranking);
                    }
    
                    returnedSearchedResultsModel.TotalNumberOfProducts = orderedProducts.Count();
    
                    var totalPagesForProducts = (int)Math.Ceiling((double)orderedProducts.Count() / (double)pageSize);
    
    
                    if (currentPage > totalPagesForProducts)
                    {
                        currentPage = totalPagesForProducts;
                    }
                    else if (currentPage < 1)
                    {
                        currentPage = 1;
                    }
    
                    returnedSearchedResultsModel.SearchedResultsForCurrentPage = orderedProducts.Skip((currentPage - 1) * pageSize).Take(pageSize);
    
                    return returnedSearchedResultsModel;
                }
    

    Thank you Kind Regards

  • Simon 692 posts 1068 karma points
    Dec 06, 2016 @ 16:59
    Simon
    0

    Just a note:

    • Maybe the needed method would be in a seperate .dll file

    • Maybe using PetaPoco

  • Simon 692 posts 1068 karma points
    Dec 07, 2016 @ 13:56
    Simon
    0

    Hi Guys,

    Any feedback on this please?

    Thank you

  • Simon 692 posts 1068 karma points
    Dec 09, 2016 @ 13:26
    Simon
    0

    Hi Rusty,

    any Feedback on this please?

    Thank you Kind Regards

  • David Peck 687 posts 1863 karma points c-trib
    Dec 09, 2016 @ 15:43
    David Peck
    0

    Are you missing a DB Index? It might also be worth rebuilding your Examine indexes.

  • Simon 692 posts 1068 karma points
    Dec 09, 2016 @ 15:46
    Simon
    0

    What do you mean Exactly David?

    As you can see above, I am querying through a LINQ statment, I'm not making an index. Or are there a way when using Merchello?

  • David Peck 687 posts 1863 karma points c-trib
    Dec 09, 2016 @ 16:50
    David Peck
    0

    Well, 10-15 seconds is far too long so unless you have 1,000s or products it strikes me that the problem is in returning all products rather than the in memory filtering that you're doing subsequently.

    You could easily prove whether there is an issue by returning 10 rows and seeing if that returns in say <100ms. If not then it sounds like there is a problem with the data layer. It is worth rebuilding your examine indexes to make sure they aren't corrupt but otherwise you might have lost a database index at some point (e.g. upgrading or scripting out the DB). If you have lost an index then you might get a very slow response.

    If it is just that you're doing too much in memory then you could cache a dictionary of your product category ids and the products to which they categorise. https://our.umbraco.org/documentation/reference/cache/updating-cache

  • Simon 692 posts 1068 karma points
    Dec 09, 2016 @ 17:09
    Simon
    0

    For example, the below code:

    var returnedProducts = merchelloHelper.Query.Product.Search(1, int.MaxValue).Items.Select(x => (ProductDisplay)x);
    

    still is taking too long to return (taken from the initial code) but I'm not that sure that it is just the LINQ clause which do the filtering.

    returnedProducts = merchelloHelper.Query.Product.Search(1, int.MaxValue).Items.Select(x => ((ProductDisplay)x).AsProductContent()).Where(x => x != null).Where(x => x.Collections().Select(p => p.CollectionKey).Intersect(listOfCategoriesGuids).Any()).Select(x => x.AsProductDisplay());
    

    I am using donut caching so the first call takes long but the subsequent is really fast.

    But still, looking at the above initial code, might I doing something wrong?

    Thanks

  • M N 125 posts 212 karma points
    Jul 12, 2017 @ 22:08
    M N
    0

    Heya Simon,

    I ran up against this as well back in version 1.x - Ended up hacking up the CachedProductQuery until I had reasonable results on my 140k+ set. Was just on the hunt to see if any love was given to searching in 2.0+, in general. It sounds like that is not the case. Guessing most people are just using this for little shops with minimal functional requirements.

    Any success achieving faster performance with Merchello on your end?

    Cheers!

Please Sign in or register to post replies

Write your reply to:

Draft