/// <summary> /// <para> /// Find items of type <see cref="T" /> which have matching keywords for the text passed /// </para> /// <para>Text is processed by the passed processor, which should be the same one that builds the keywords for the elements</para> /// <para> /// The search is ranked by Tf-idf <seealso cref="http://en.wikipedia.org/wiki/Tf%E2%80%93idf" /> /// </para> /// </summary> /// <typeparam name="T">Entity Type</typeparam> /// <param name="source"> /// Queryable source of <see cref="T" /> /// </param> /// <param name="text">Text to find</param> /// <param name="keywordProcessor">Processes the text into keywords to search on</param> /// <returns>Matching ranked elements</returns> public static IQueryable <T> Match <T>( this IQueryable <T> source, string text, IKeywordProcessor keywordProcessor) where T : IndexedEntity { Contract.Requires(source != null); Contract.Requires(!string.IsNullOrWhiteSpace(text)); Contract.Requires(keywordProcessor != null); var keywords = keywordProcessor.Process(text, true); return (from e in source let rank = ( from ek in e.Keywords where keywords.Any(k => ek.Keyword.Value.StartsWith(k)) select ek.Frequency / (decimal)ek.Keyword.Frequency ).Sum() where rank > 0 orderby rank descending select e); }
public IKeywordsBuilder <T> Index(Func <T, string> func) { _items.Add(e => _processor.Process(func(e))); return(this); }