C# – Should a Search Engine Return a Dictionary or Strongly Typed Objects?

ccode-reusecode-reviewsdomain-driven-design

I'm building a search engine using Lucene.NET / Solr.NET, and I'm wondering should search hits be returned as a dictionary or strongly typed object.

public class SearchResult
{
    public string SearchTerm { get; set; }
    public List<Dictionary<string, object>> SearchHits { get; set; }
    ...
}

// where search hit looks like this
Dictionary<string, object> searchHit = new Dictionary<string, object>
{
    { "Name", "John Doe" },
    { "Address", "Some street" },
};

vs

public class SearchResult
{
    public string SearchTerm { get; set; }
    public List<Foo> SearchHits { get; set; }
    ...
}

// where search hit looks like this
var searchHit = new SearchHit
{
    Name = "John Doe",
    Address = "Some address"
};

I will be indexing different types of objects (People, Web pages, Files, etc.).
Each object has a different set of properties (people have name and address, while web pages have URLs and titles), and search hits don't have the same set of properties as original objects (WebPage class has the MainContent property, but after indexing, the search hit that represents this object will have the PreviewText property (the first 300 characters of MainContent property with stripped HTML tags).

I don't want to duplicate the code all over the place and have: IPeopleSearchService, IWebPagesSearchService, IFilesSearchService, etc. and corresponding search results: PeopleSearchResult, FileSearchResult, etc.

interface IFooService
{
    FooSearchResult Search(string text);
    void Index(Foo foo);
    ...
}

interface IBarService
{
    BarSearchResult Search(string text);
    void Index(Bar bar);
    ...
}
...

I would like to have a more generic solution, but I don't like over-complexity. It should be readable and easily understandable by junior developer.

interface ISearchService<TEntity, TSearchHit>
{
    SearchResult<TSearchHit> Search(string text);
    void Index(TEntity entity);
}

How would you design such a system? Any help would be greatly appreciated!

Best Answer

Basically, what you're asking is: should I make the search results statically typed? I think the answer depends on what you're going to do with them and how much do you like static typing.

Regarding what you're going to do: if you're just going to display the results to the user, or something like that that treats all the fields in the search result equally, then using a Dictionary (which is basically the same as dynamic typing) makes sense. On the other hand, if you're often going to write things like searchHist.Address (or searchHit["Address"]), then that points more to static typing.

Regarding how much you like static typing: to me, as a proponent of static typing, using dynamic typing gives you small short term advantage (e.g. you don't have to write those dozen lines declaring each TSearchHit) for significant long term disadvantages (no compiler checking for typos, no IntelliSense). This means that I think static typing is almost always worth the up-front cost. Proponents of dynamic typing would tell you otherwise, but C# is mostly statically typed language, and presumably you're using that for a reason.