예제 #1
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());
        }
예제 #2
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());
        }