I have a set of objects of type Idea
public class Idea
{
public string Title { get; set; }
public string Body { get; set; }
}
I want to search this objects by substring. For example when I have object of title "idea", I want it to be found when I enter any substring of "idea": i, id, ide, idea, d, de, dea, e, ea, a.
I'm using RavenDB for storing data. The search query looks like that:
var ideas = session
.Query<IdeaByBodyOrTitle.IdeaSearchResult, IdeaByBodyOrTitle>()
.Where(x => x.Query.Contains(query))
.As<Idea>()
.ToList();
while the index is following:
public class IdeaByBodyOrTitle : AbstractIndexCreationTask<Idea, IdeaByBodyOrTitle.IdeaSearchResult>
{
public class IdeaSearchResult
{
public string Query;
public Idea Idea;
}
public IdeaByBodyOrTitle()
{
Map = ideas => from idea in ideas
select new
{
Query = new object[] { idea.Title.SplitSubstrings().Concat(idea.Body.SplitSubstrings()).Distinct().ToArray() },
idea
};
Indexes.Add(x => x.Query, FieldIndexing.Analyzed);
}
}
SplitSubstrings()
is an extension method which returns all distinct substrings of given string:
static class StringExtensions
{
public static string[] SplitSubstrings(this string s)
{
s = s ?? string.Empty;
List<string> substrings = new List<string>();
for (int i = 0; i < s.Length; i++)
{
for (int j = 1; j <= s.Length - i; j++)
{
substrings.Add(s.Substring(i, j));
}
}
return substrings.Select(x => x.Trim()).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToArray();
}
}
This is not working. Particularly because RavenDB is not recognizing SplitSubstrings()
method, because it is in my custom assembly. How to make this work, basically how to force RavenDB to recognize this method ? Besides that, is my approach appropriate for this kind of searching (searching by substring) ?
EDIT
Basically, I want to build auto-complete feature on this search, so it need to be fast.
Btw: I'm using RavenDB - Build #960