コード例 #1
0
ファイル: GatewayTests.cs プロジェクト: Fanuer/HIS
        public async Task SearchForRecipesByIngrediantFuzzy()
        {
            using (var client = await this.CreateExternalClient())
            {
                var recipe = await client.GetRecipes(entriesPerPage : Int32.MaxValue);

                var firstRecipe = recipe.Entries.First();
                var ingrediants = await client.GetRecipeIngrediantsAsync(firstRecipe.Id);

                var searchModel = new RecipeSearchViewModel()
                {
                    Ingrediants = new List <string>()
                    {
                        ingrediants.First().Name + "ABC"
                    }
                };

                var result = await client.GetRecipes(searchModel);

                Assert.NotNull(result);
                Assert.NotNull(result.Entries);
                Assert.NotEmpty(result.Entries);
                Assert.True(result.Entries.Any(x => x.Id.Equals(firstRecipe.Id)));
            }
        }
コード例 #2
0
        public async Task <IActionResult> Search(string searchInfo, string searchType)
        {
            var pageNumber = 1;

            var model = new RecipeSearchViewModel();

            model.Recipes = new List <Result>();

            if (!String.IsNullOrEmpty(searchInfo))
            {
                if (searchType == "AllRecipes")
                {
                    do
                    {
                        var response = await _RecipeClient.GetAllRecipes(pageNumber);

                        foreach (var recipe in response.results)
                        {
                            if (recipe.title.Contains(searchInfo, StringComparison.OrdinalIgnoreCase))
                            {
                                model.Recipes.Add(recipe);
                            }
                        }

                        pageNumber = pageNumber + 1;
                    }while (pageNumber < 100);
                }
            }
            return(View(model));
        }
コード例 #3
0
ファイル: GatewayTests.cs プロジェクト: Fanuer/HIS
        public async Task SearchForRecipesByName()
        {
            using (var client = await this.CreateExternalClient())
            {
                var allRecipe = await client.GetRecipes();

                var searchModel = new RecipeSearchViewModel()
                {
                    Name = allRecipe.Entries.First().Name
                };

                var result = await client.GetRecipes(searchModel);

                Assert.NotNull(result);
                Assert.NotNull(result.Entries);
                Assert.NotEmpty(result.Entries);
                Assert.Equal(1, result.Entries.Count());

                var firstResult   = result.Entries.First();
                var compareRecipe = result.Entries.First();

                Assert.Equal(compareRecipe.Name, firstResult.Name);
                Assert.Equal(compareRecipe.Creator, firstResult.Creator);
                Assert.Equal(compareRecipe.Id, firstResult.Id);
            }
        }
コード例 #4
0
        public async Task <IQueryable <ShortRecipeViewModel> > SearchForRecipes(RecipeSearchViewModel searchModel)
        {
            IQueryable <ShortRecipeViewModel> result = null;

            try
            {
                var recipes = this.Repository
                              .GetAll()
                              .Include(x => x.Images)
                              .Include(x => x.Tags)
                              .ThenInclude(x => x.RecipeTag);

                var searchresult = await this.SearchForRecipes(recipes, searchModel);

                result = searchresult
                         .OrderByDescending(x => x.CookedCounter)
                         .ThenByDescending(x => x.LastTimeCooked)
                         .ProjectTo <ShortRecipeViewModel>(this.Mapper.ConfigurationProvider);

                this.Logger.LogDebug(new EventId(), $"Returned all recipes");
            }
            catch (Exception e)
            {
                this.Logger.LogError(new EventId(), e, $"Error on receiving all recipes");
                throw new Exception($"Error on receiving all recipes");
            }
            return(result);
        }
コード例 #5
0
ファイル: RecipeDialog.cs プロジェクト: Fanuer/HIS
        private RecipeSearchViewModel CreateSearchModel(LuisResult result)
        {
            EntityRecommendation recipeName;

            if (!result.TryFindEntity(Entity_Recipename, out recipeName))
            {
                recipeName = new EntityRecommendation(type: Entity_Recipename)
                {
                    Entity = ""
                };
            }

            IList <EntityRecommendation> ingrediants;

            if (!result.TryFindEntity(Entity_Ingrediant, out ingrediants))
            {
                ingrediants = new List <EntityRecommendation>();
            }

            IList <EntityRecommendation> tags;

            if (!result.TryFindEntity(Entity_Tag, out tags))
            {
                tags = new List <EntityRecommendation>();
            }

            var searchModel = new RecipeSearchViewModel()
            {
                Tags        = tags.Where(x => !String.IsNullOrWhiteSpace(x.Entity)).Select(x => x.Entity.Replace(" ", "")).ToList(),
                Ingrediants = ingrediants.Where(x => !String.IsNullOrWhiteSpace(x.Entity)).Select(x => x.Entity.Replace(" ", "")).ToList(),
                Name        = recipeName.Entity
            };

            return(searchModel);
        }
コード例 #6
0
ファイル: GatewayClient.cs プロジェクト: Fanuer/HIS
        public async Task <ListViewModel <ShortRecipeViewModel> > GetRecipes(RecipeSearchViewModel searchModel, int page = 0, int entriesPerPage = 5)
        {
            await this.SetBearerTokenAsync(HttpContext.Current);

            var newUrl = new Uri(this._client.BaseAddress, "Recipes/");
            var query  = $"?{nameof(page)}={page}&{nameof(entriesPerPage)}={entriesPerPage}";

            if (searchModel != null)
            {
                query += $"&{this._client.ConvertToQueryString(searchModel)}";
            }

            return(await this._client.GetAsync <ListViewModel <ShortRecipeViewModel> >(new Uri(newUrl, query).ToString()));
        }
コード例 #7
0
        public async Task <IActionResult> RecipeIndexResult(RecipeSearchViewModel model)
        {
            var response = await _recipeClient.GetAllRecipes(model.ingredient, model.title, model.page);

            var viewModel = new RecipeIndexViewModel();

            viewModel.results = response.results
                                .Select(response => new ResultsViewModel()
            {
                title = response.title, href = response.href, thumbnail = response.thumbnail
            })
                                .ToList();

            return(View(viewModel));
        }
コード例 #8
0
ファイル: GatewayClient.cs プロジェクト: Fanuer/HIS
        public async Task <ListViewModel <ShortRecipeViewModel> > GetRecipes(RecipeSearchViewModel searchModel = null, int page = 0, int entriesPerPage = 10)
        {
            var newUrl = new Uri(this.Client.BaseAddress, "Recipes/");
            var query  = "";

            if (searchModel != null)
            {
                var searchQuery = this.Client.ConvertToQueryString(searchModel);
                if (!String.IsNullOrWhiteSpace(searchQuery))
                {
                    query = $"?{searchQuery}";
                }
            }

            query = QueryHelpers.AddQueryString(query, nameof(page), page.ToString());
            query = QueryHelpers.AddQueryString(query, nameof(entriesPerPage), entriesPerPage.ToString());

            return(await this.Client.GetAsync <ListViewModel <ShortRecipeViewModel> >(new Uri(newUrl, query).ToString()));
        }
コード例 #9
0
        public async Task SearchForRecipesByName()
        {
            await InitializeAsync();

            using (var service = GetService())
            {
                var firstRecipe = await this.DbContext.Recipes.FirstAsync();

                var searchModel = new RecipeSearchViewModel()
                {
                    Name = firstRecipe.Name
                };


                var output = await(await service.SearchForRecipes(searchModel)).ToListAsync();
                Assert.NotNull(output);
                Assert.NotEmpty(output);
                Assert.Equal(1, output.Count);
            }
        }
コード例 #10
0
        // GET: Recipes
        public ActionResult Index(RecipeSearchViewModel model)
        {
            var recipes = db.Recipes.Include(r => r.Chef).Include(r => r.Country);

            if (model?.Continent_Id != null)
            {
                recipes = recipes.Where(R => R.Country.Continent_Id == model.Continent_Id);
            }
            if (model?.Country_Id != null)
            {
                recipes = recipes.Where(R => R.Country_Id == model.Country_Id);
            }
            if (!string.IsNullOrWhiteSpace(model.Search_KeyWord))
            {
                recipes = recipes.Where(R => R.Dish_Description.Contains(model.Search_KeyWord) ||
                                        R.Ingredients.Contains(model.Search_KeyWord) || R.Directions.Contains(model.Search_KeyWord));
            }

            return(View(recipes.ToList()));
        }
コード例 #11
0
        public async Task <IActionResult> Index(int pageNumber)
        {
            var model = new RecipeSearchViewModel();

            model.Recipes = new List <Result>();

            var response = await _RecipeClient.GetAllRecipes(pageNumber);



            foreach (var recipe in response.results)
            {
                model.Recipes.Add(recipe);
            }

            model.currentPageNumber  = pageNumber;
            model.nextPageNumber     = pageNumber + 1;
            model.previousPageNumber = pageNumber - 1;

            return(View(model));
        }
コード例 #12
0
        public async Task SearchForRecipesByTag()
        {
            await InitializeAsync();

            using (var service = GetService())
            {
                var tagWith     = this.DbContext.RecipeTags.Include(x => x.Recipes).First(x => x.Recipes.Any());
                var searchModel = new RecipeSearchViewModel()
                {
                    Tags = new List <string>()
                    {
                        tagWith.Name
                    }
                };

                var output = await(await service.SearchForRecipes(searchModel)).ToListAsync();
                Assert.NotNull(output);
                Assert.NotEmpty(output);
                Assert.Equal(tagWith.Recipes.Count, output.Count);
            }
        }
コード例 #13
0
ファイル: GatewayTests.cs プロジェクト: Fanuer/HIS
        public async Task SearchForRecipesByTagFuzzy()
        {
            using (var client = await this.CreateExternalClient())
            {
                var recipe = await client.GetRecipes();

                var firstTagRecipe = recipe.Entries.First(x => x.Tags.Any());
                var searchModel    = new RecipeSearchViewModel()
                {
                    Tags = new List <string>()
                    {
                        firstTagRecipe.Tags.First() + "ABC"
                    }
                };

                var result = await client.GetRecipes(searchModel);

                Assert.NotNull(result);
                Assert.NotNull(result.Entries);
                Assert.NotEmpty(result.Entries);
                Assert.True(result.Entries.Any(x => x.Id.Equals(firstTagRecipe.Id)));
            }
        }
コード例 #14
0
ファイル: GatewayTests.cs プロジェクト: Fanuer/HIS
        public async Task SearchForRecipesByIngrediantWithDirectName()
        {
            using (var client = await this.CreateExternalClient())
            {
                var ingrediantName = "salat";
                var searchModel    = new RecipeSearchViewModel()
                {
                    Ingrediants = new List <string>()
                    {
                        ingrediantName
                    }
                };

                var result = await client.GetRecipes(searchModel);

                Assert.NotNull(result);
                Assert.NotNull(result.Entries);
                Assert.NotEmpty(result.Entries);
                var ingrediants = await client.GetRecipeIngrediantsAsync(result.Entries.First().Id);

                Assert.True(ingrediants.Any(x => x.Name.Equals(ingrediantName, StringComparison.CurrentCultureIgnoreCase)));
            }
        }
コード例 #15
0
ファイル: RecipesController.cs プロジェクト: Fanuer/HIS
        public async Task <ListViewModel <ShortRecipeViewModel> > GetRecipesAsync([FromQuery] RecipeSearchViewModel searchModel, [FromQuery] int page = 0, [FromQuery] int entriesPerPage = 10)
        {
            int recipeCount = 0;
            List <ShortRecipeViewModel> result = new List <ShortRecipeViewModel>();

            try
            {
                IQueryable <ShortRecipeViewModel> entries = null;
                if (searchModel != null && searchModel.IsFilled())
                {
                    entries = await _service.SearchForRecipes(searchModel);
                }
                else
                {
                    entries = _service.GetRecipes();
                }

                recipeCount = await entries.CountAsync();

                result = await entries
                         .Skip(page *entriesPerPage)
                         .Take(entriesPerPage)
                         .ToListAsync();

                foreach (var shortRecipeViewModel in result)
                {
                    shortRecipeViewModel.Url = this.Url.RouteUrl("GetRecipeById", new { id = shortRecipeViewModel.Id });
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }

            return(new ListViewModel <ShortRecipeViewModel>(result, recipeCount, page + 1, entriesPerPage));
        }
コード例 #16
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ArticleListPage" /> class.
 /// </summary>
 public RecipeSearchPage()
 {
     InitializeComponent();
     BindingContext = new RecipeSearchViewModel(Navigation);
 }
コード例 #17
0
 public PartialViewResult SearchRecipes(RecipeSearchViewModel vm)
 {
     return PartialView("_SearchRecipes", RecipeManager.SearchRecipes(vm.PageNumber,
         vm.PageSize, vm.SortType, vm.DataFilter));
 }
コード例 #18
0
 public PartialViewResult SearchRecipes(RecipeSearchViewModel vm)
 {
     return(PartialView("_SearchRecipes", RecipeManager.SearchRecipes(vm.PageNumber,
                                                                      vm.PageSize, vm.SortType, vm.DataFilter)));
 }
コード例 #19
0
        public async Task <IActionResult> GetRecipesAsync([FromQuery] RecipeSearchViewModel searchModel, [FromQuery] int page = 0, [FromQuery] int entriesPerPage = 10)
        {
            await Client.SetBearerTokenAsync(this.HttpContext);

            return(Ok(await this.Client.GetRecipes(searchModel, page, entriesPerPage)));
        }
コード例 #20
0
        private async Task <IQueryable <Recipe> > SearchForRecipes(IQueryable <Recipe> recipes, RecipeSearchViewModel searchModel)
        {
            if (recipes == null)
            {
                throw new ArgumentNullException(nameof(recipes));
            }

            if (searchModel == null)
            {
                return(recipes);
            }

            if (!String.IsNullOrWhiteSpace(searchModel.Name))
            {
                recipes = recipes.Where(x => x != null && x.Name != null && x.Name.ToLower().Contains(searchModel.Name.ToLower()));
            }
            if (searchModel.Tags != null && searchModel.Tags.Any())
            {
                var hits = await GetRecipesForTagSearchQuery(recipes.Include(x => x.Tags).ThenInclude(x => x.RecipeTag), searchModel);

                recipes = recipes.Where(x => x.Tags.Any(tag => hits.Contains(tag.RecipeTagId)));
            }
            if (searchModel.Ingrediants != null && searchModel.Ingrediants.Any())
            {
                var hits = await GetRecipesForIngrediantsSearchQuery(recipes.Include(x => x.Ingrediants).ThenInclude(x => x.Ingrediant), searchModel);

                recipes = recipes.Where(x => x.Ingrediants.Any(ingrediant => hits.Contains(ingrediant.IngrediantId)));
            }
            return(recipes);
        }
コード例 #21
0
        private async Task <IEnumerable <int> > GetRecipesForTagSearchQuery(IIncludableQueryable <Recipe, RecipeTag> recipes, RecipeSearchViewModel model)
        {
            Dictionary <string, int> allEntries = null;
            var hits = new List <int>();

            try
            {
                foreach (var searchModelTag in model.Tags)
                {
                    // check if tag are found within database
                    IEnumerable <int> currentHits = await recipes.SelectMany(x => x.Tags).Where(x => x.RecipeTag.Name.Contains(searchModelTag, true)).Select(x => x.RecipeTagId).ToListAsync();

                    if (currentHits.Any())
                    {
                        hits.AddRange(currentHits);
                        Logger.LogDebug($"Found fuzzy result in source data. Searched for {model}. Found {currentHits}");
                        continue;
                    }

                    // if no hits, lookup for fuzzy search cache for search query
                    currentHits = await Repository.GetCachedFuzzyResultAsync(nameof(RecipeTag), searchModelTag);

                    if (currentHits.Any())
                    {
                        hits.AddRange(currentHits);
                        Logger.LogDebug($"Found fuzzy result in cache data. Searched for {model}. Found {currentHits}");
                        continue;
                    }

                    // If no hits available, load all elements and process a fuzzy search on them
                    // TODO: Change to 'real' caching (e.g. Lucene)
                    if (allEntries == null)
                    {
                        // must be here to enable navigation property for RecipeTags
                        var recipe = await recipes.FirstOrDefaultAsync();

                        allEntries = await recipes
                                     .SelectMany(x => x.Tags)
                                     .Select(x => x.RecipeTag)
                                     .Where(x => x != null)
                                     .Distinct()
                                     .ToDictionaryAsync(x => x.Name, x => x.Id);
                    }

                    var fuzzyHits = allEntries.Keys.Where(x => x.ApproximatelyEquals(searchModelTag, FuzzyStringComparisonTolerance.Normal, FuzzyStringComparisonOptions.UseLevenshteinDistance)).ToList();
                    if (!fuzzyHits.Any())
                    {
                        Logger.LogDebug($"No result found for fuzzy search. Searched for {model}");
                        continue;
                    }

                    // if hit is found, save to cache for reuse
                    foreach (var entry in fuzzyHits)
                    {
                        var newEntry = new FuzzyEntry()
                        {
                            Id = allEntries[entry], SearchQuery = searchModelTag, Type = nameof(RecipeTag)
                        };
                        await Repository.SaveFuzzyEntryAsync(newEntry);

                        hits.Add(allEntries[entry]);
                        Logger.LogDebug($"Found data after calculating cache result. Searched for {model}. Found {entry} ({allEntries[entry]})");
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw e;
            }
            return(hits.Distinct());
        }
コード例 #22
0
        private async Task <IEnumerable <int> > GetRecipesForIngrediantsSearchQuery(IIncludableQueryable <Recipe, Ingrediant> recipes, RecipeSearchViewModel model)
        {
            Dictionary <string, int> allEntries = null;
            var hits = new List <int>();

            try
            {
                foreach (var searchIngrediant in model.Ingrediants)
                {
                    // check if tag are found within database
                    IEnumerable <int> currentHits = await recipes
                                                    .SelectMany(x => x.Ingrediants)
                                                    .Where(ingrediant => ingrediant.Ingrediant.Name.Contains(searchIngrediant, true))
                                                    .Select(x => x.IngrediantId)
                                                    .ToListAsync();

                    if (currentHits.Any())
                    {
                        Logger.LogDebug($"Found fuzzy result in source data. Searched for {model}. Found {currentHits}");
                        hits.AddRange(currentHits);
                        continue;
                    }

                    // if no hits, lookup for fuzzy search cache for search query
                    currentHits = await Repository.GetCachedFuzzyResultAsync(nameof(Ingrediant), searchIngrediant);

                    if (currentHits.Any())
                    {
                        Logger.LogDebug($"Found fuzzy result in cache data. Searched for {model}. Found {currentHits}");
                        hits.AddRange(currentHits);
                        continue;
                    }

                    // If no hits available, load all elements and process a fuzzy search on them
                    // TODO: Change to 'real' caching (e.g. Lucene)
                    if (allEntries == null)
                    {
                        var peng = await recipes.FirstOrDefaultAsync();

                        allEntries = await recipes
                                     .SelectMany(x => x.Ingrediants)
                                     .Select(x => x.Ingrediant)
                                     .Where(x => x != null)
                                     .Distinct()
                                     .ToDictionaryAsync(x => x.Name, x => x.Id);
                    }
                    var fuzzyoptions = new[]
                    {
                        FuzzyStringComparisonOptions.UseJaccardDistance,
                        FuzzyStringComparisonOptions.UseLongestCommonSubstring,
                        FuzzyStringComparisonOptions.UseSorensenDiceDistance
                    };

                    var fuzzyHits = allEntries.Keys.Where(x => x.ApproximatelyEquals(searchIngrediant, FuzzyStringComparisonTolerance.Normal, fuzzyoptions)).ToList();

                    if (!fuzzyHits.Any())
                    {
                        Logger.LogDebug($"No result found for fuzzy search. Searched for {model}");
                        continue;
                    }


                    // if hit is found, save to cache for reuse
                    foreach (var entry in fuzzyHits)
                    {
                        var newEntry = new FuzzyEntry()
                        {
                            Id = allEntries[entry], SearchQuery = searchIngrediant, Type = nameof(Ingrediant)
                        };
                        await Repository.SaveFuzzyEntryAsync(newEntry);

                        hits.Add(allEntries[entry]);
                        Logger.LogDebug($"Found data after calculating cache result. Searched for {model}. Found {entry} ({allEntries[entry]})");
                    }
                }
            }
            catch (Exception e)
            {
                this.Logger.LogError(new EventId(), e, $"Error on fuzzy search. Searched for {model}");
            }
            return(hits.Distinct());
        }