I need to make a search based on a set of keywords, that return all the Ads related with those keywords. Then the result is a list of Categories with the Ads Count for each
I have posted my answer to: https://github.com/n074v41l4bl34u/StackOverflow19796132 Feel free to review it.
Here is the most important snippet.
with:
internal class SearchDomain
{
public List Keywords { get; set; }
public List Categories { get; set; }
public List KeywordAdCategories { get; set; }
}
then:
private static char[] keywordPartsSplitter = new char[] { ' ', '-' };
internal static Dictionary>> FromStringInput(string searchPhrase, SearchDomain searchDomain)
{
var identifiedKeywords = searchPhrase
.Split(keywordPartsSplitter);
var knownKeywordParts = identifiedKeywords
.Where
(ik =>
searchDomain
.Keywords
.SelectMany(x => x.GetKeywordParts())
.Any(kp => kp.Equals(ik, StringComparison.InvariantCultureIgnoreCase))
);
var keywordkSearches = knownKeywordParts
.Select((kkp, n) => new KeywordSearch()
{
Id = n,
Name = kkp,
Keyword = searchDomain
.Keywords
.Single
(k =>
k.GetKeywordParts()
.Any(kp => kp.Equals(kkp, StringComparison.InvariantCultureIgnoreCase))
)
});
var relevantKeywords = keywordkSearches
.Select(ks => ks.Keyword)
.Distinct();
var keywordAdCategoriesByCategory = searchDomain.Categories
.GroupJoin
(
searchDomain.KeywordAdCategories,
c => c.Id,
kac => kac.Category_Id,
(c, kac) => new { Category = c, AdKeywordsForCategory = kac }
);
var relevantKeywordAdCategories = keywordAdCategoriesByCategory
.Where
(kacbk =>
relevantKeywords
.All
(rk =>
kacbk
.AdKeywordsForCategory
.Any(kac => kac.Keyword_Id == rk.Id)
)
);
var foundAdsInCategories = relevantKeywordAdCategories
.ToDictionary
(rkac =>
rkac.Category,
rkac => rkac.AdKeywordsForCategory
.GroupBy(g => g.Ad_Id)
.ToDictionary(x => x.Key, x => x.ToList())
);
return foundAdsInCategories;
}
It does exactly what you want however I find something fishy about keywords being divisible to sub-keywords. Than again, maybe it is just the naming.