Query Extension Logic in C #
I need to write logic to extend queries for solr search engine. I am using
Dictionary<string, string> dicSynon = new Dictionary<string, string>();
.
Every time I get lines like "2 ln ca". In my dictionary, I have synonyms for ln and ca as lane and california. Now I need to pass the entire string combination to solr. Like this
2 ln ca
2 lane ca
2 lane california
2 ln california
Please help me build the logic ....
source to share
This is an exercise in using combinatorics and Linqs SelectMany:
First you need to write some function to give you a sequence of synonyms given the word (including the word, so "2" will result in ("2")) - let this "Synonmys" - using a dictionary it might look like this:
private Dictionary<string, IEnumerable<string>> synonyms = new Dictionary<string, IEnumerable<string>>();
public IEnumerable<string> GetSynonmys(string word)
{
return synonyms.ContainsKey(word) ? synonyms[word] : new[]{word};
}
(you have to fill in the dictionary yourself)
You have such a task quite simply - think about it. You have to combine each synonym of a word with all the combinations you get from completing the task, the rest of the words is exactly where you can use SelectMany (I only insert the rest, separated by a space, maybe you need to reorganize the bit) - The algorithm is yours standard recursive combinational algorithm - you'll see this a lot if you know a problem like this:
public string[] GetWords(string text)
{
return text.Split(new[]{' '}); // add more seperators if you need
}
public IEnumerable<string> GetCombinations(string[] words, int lookAt = 0)
{
if (lookAt >= words.Length) return new[]{""};
var currentWord = words[lookAt];
var synonymsForCurrentWord = GetSynonmys(currentWord);
var combinationsForRest = GetCombinations(words, lookAt + 1);
return synonymsForCurrentWord.SelectMany(synonym => combinationsForRest.Select(rest => synonym + " " + rest));
}
Here's a complete example:
class Program
{
static void Main(string[] args)
{
var test = new Synonmys(Tuple.Create("ca", "ca"),
Tuple.Create("ca", "california"),
Tuple.Create("ln", "ln"),
Tuple.Create("ln", "lane"));
foreach (var comb in test.GetCombinations("2 ln ca"))
Console.WriteLine("Combination: " + comb);
}
}
class Synonmys
{
private Dictionary<string, IEnumerable<string>> synonyms;
public Synonmys(params Tuple<string, string>[] syns )
{
synonyms = syns.GroupBy(s => s.Item1).ToDictionary(g => g.Key, g => g.Select(kvp => kvp.Item2));
}
private IEnumerable<string> GetSynonmys(string word)
{
return synonyms.ContainsKey(word) ? synonyms[word] : new[]{word};
}
private string[] GetWords(string text)
{
return text.Split(new[]{' '}); // add more seperators if you need
}
private IEnumerable<string> GetCombinations(string[] words, int lookAt = 0)
{
if (lookAt >= words.Length) return new[]{""};
var currentWord = words[lookAt];
var synonymsForCurrentWord = GetSynonmys(currentWord);
var combinationsForRest = GetCombinations(words, lookAt + 1);
return synonymsForCurrentWord.SelectMany(synonym => combinationsForRest.Select(rest => synonym + " " + rest));
}
public IEnumerable<string> GetCombinations(string text)
{
return GetCombinations(GetWords(text));
}
}
Feel free to comment if something is not crystal clear here;)
source to share