public ItemInfoMessageEntity SearchItems(string userSubscriptionToken, string queryString, int[] maxHitsPerCategory, IShopgunWebOperationContext shopgunWebOperationContext)
        {
            var result = new ItemInfoMessageEntity();

            var queryStrings = queryString.Split(new [] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

            using (var productRepository = _repositoryFactory.Build <IRepository <Product>, Product>())
            {
                result.Products =
                    (from p in
                     productRepository.Find(
                         x => queryStrings.All(q => (x.ProductName + " " + x.Brand.BrandName).ToLower().Contains(q)))
                     orderby p.ProductName
                     select new ProductInfo
                {
                    ProductId = p.Id,
                    ProductName = p.ProductName,
                    BrandName = p.Brand.BrandName,
                    CompanyName = p.Brand.Owner != null ? p.Brand.Owner.CompanyName : ""
                    ,
                    NumberAdvices =
                        p.ProductAdvices.Count(x => x.Published) +
                        _ingredientApplicationService.FindIngredientsForTableOfContents(
                            p.TableOfContent).SelectMany(
                            x => x.IngredientAdvices.Where(a => a.Published)).Count()
                }).Take(maxHitsPerCategory[0]).ToList();
            }

            return(result);
        }
        public ItemInfoMessageEntity SearchListInfo(string userSubscriptionToken, string queryString, int maxNumHitsPerCategory, IShopgunWebOperationContext shopgunWebOperationContext)
        {
            var result = new ItemInfoMessageEntity();

            using (var productRepository = _repositoryFactory.Build <IRepository <Product>, Product>())
            {
                // Search by productname
                var productHits = (from p in productRepository.Find(x => x.ProductName.StartsWith(queryString))
                                   orderby p.ProductName
                                   select new ProductInfo
                {
                    ProductId = p.Id,
                    ProductName = p.ProductName,
                    GTIN = p.GlobalTradeItemNumber,
                    BrandName = p.Brand.BrandName,
                    CompanyName = p.Brand.Owner != null ? p.Brand.Owner.CompanyName : "",
                    NumberAdvices = 0,
                    //p.ProductAdvices.Count(x => x.Published) +
                    //_ingredientApplicationService.FindIngredientsForTableOfContents(
                    //    p.TableOfContent).SelectMany(
                    //        x => x.IngredientAdvices.Where(a => a.Published)).Count()
                }).Take(maxNumHitsPerCategory).ToList();

                // Search by GTIN
                productHits.AddRange(
                    (from p in productRepository.Find(x => x.GlobalTradeItemNumber.StartsWith(queryString))
                     orderby p.ProductName
                     select new ProductInfo
                {
                    ProductId = p.Id,
                    ProductName = p.ProductName,
                    GTIN = p.GlobalTradeItemNumber,
                    BrandName = p.Brand.BrandName,
                    CompanyName = p.Brand.Owner != null ? p.Brand.Owner.CompanyName : "",
                    NumberAdvices = 0
                }).Take(maxNumHitsPerCategory).ToList());

                result.Products = productHits.OrderBy(x => x.ProductName).ToList();
            }

            using (var ingredientRepository = _repositoryFactory.Build <IRepository <Ingredient>, Ingredient>())
            {
                // search in ingredients
                var ingredients  = ingredientRepository.Find(x => x.IngredientName.StartsWith(queryString));
                var searchResult = (from i in ingredients
                                    orderby i.IngredientName
                                    select new IngredientInfo
                {
                    IngredientId = i.Id,
                    IngredientName = i.IngredientName,
                    NumberAdvices = 0,                               //CountIngredientAdvicesRecursively(ingredientRepository, i)
                }).Take(maxNumHitsPerCategory).ToList();

                using (var alternativeNameRepository = _repositoryFactory.Build <IRepository <AlternativeIngredientName>, AlternativeIngredientName>())
                {
                    //search in AlternativeIngredientNames but leave out those which were already added by ingredient search
                    var alternativeNameIngredients =
                        (from altNameIngredient in
                         alternativeNameRepository.Find(x => x.AlternativeName.StartsWith(queryString))
                         where !ingredients.Contains(altNameIngredient.Ingredient)
                         select new IngredientInfo
                    {
                        IngredientId = altNameIngredient.Ingredient.Id,
                        IngredientName = altNameIngredient.AlternativeName,
                        NumberAdvices = 0,                //CountIngredientAdvicesRecursively(ingredientRepository, altNameIngredient.Ingredient)//altNameIngredient.Ingredient.IngredientAdvices.Where(x => x.Published).Count()
                    }).Take(maxNumHitsPerCategory).ToList();
                    searchResult.AddRange(alternativeNameIngredients);
                }
                // reorder, take max amount and set result
                result.Ingredients = searchResult.OrderBy(x => x.IngredientName).Take(maxNumHitsPerCategory).ToList();
            }

            using (var brandRepository = _repositoryFactory.Build <IRepository <Brand>, Brand>())
            {
                result.Brands = (from b in brandRepository.Find(x => x.BrandName.StartsWith(queryString))
                                 orderby b.BrandName
                                 select
                                 new BrandInfo
                {
                    BrandId = b.Id,
                    BrandName = b.BrandName,
                    CompanyName = b.Owner != null ? b.Owner.CompanyName : "",
                    NumberAdvices = 0,                         //b.BrandAdvices.Count(x => x.Published)
                }).Take(maxNumHitsPerCategory).ToList();
            }

            using (var companyRepository = _repositoryFactory.Build <IRepository <Company>, Company>())
            {
                result.Companies = (from c in companyRepository.Find(x => x.CompanyName.StartsWith(queryString))
                                    orderby c.CompanyName
                                    select
                                    new CompanyInfo
                {
                    CompanyId = c.Id,
                    CompanyName = c.CompanyName,
                    NumberAdvices = 0,                            //c.CompanyAdvices.Count(x => x.Published)
                }).Take(
                    maxNumHitsPerCategory).ToList();
            }

            using (var countryRepository = _repositoryFactory.Build <IRepository <Country>, Country>())
            {
                result.Countries = (from c in countryRepository.Find(x => x.CountryCode.Name.StartsWith(queryString))
                                    orderby c.CountryCode.Name
                                    select
                                    new CountryInfo
                {
                    CountryId = c.Id,
                    CountryName = c.CountryCode.Name,
                    NumberAdvices = 0,                            //c.CountryAdvices.Count(x => x.Published)
                }).Take(
                    maxNumHitsPerCategory).ToList();
            }

            using (var conceptRepository = _repositoryFactory.Build <IRepository <Concept>, Concept>())
            {
                result.Concepts = (from c in conceptRepository.Find(x => x.ConceptTerm.StartsWith(queryString))
                                   orderby c.ConceptTerm
                                   select
                                   new ConceptInfo
                {
                    ConceptId = c.Id,
                    ConceptName = c.ConceptTerm,
                    NumberAdvices = 0,                           //c.ConceptAdvices.Count(x => x.Published)
                }).Take(
                    maxNumHitsPerCategory).ToList();
            }

            return(result);
        }