Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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!

share|improve this question
    
So, what's wrong with the generic interface you posted? It doesn't look overly complex to me. –  svick Jul 22 '13 at 18:59
    
For every TEntity I have to define TSearchHit. Does this look like overkill? Would I benefit from returning a Dictionary instead of TSearchHit? –  šljaker Jul 22 '13 at 19:04
    
Or can I just have one search service that has Dictionary<string, object> Search (string text, IEntityMappingStrategy mapper) and void Index (object entity, IEntityMappingStrategy mapper) methods, and then define / instantiate different strategies for each entity? Would that be more SOLID? –  šljaker Jul 22 '13 at 19:13

2 Answers 2

up vote 1 down vote accepted

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.

share|improve this answer

I'm not familiar with Lucene.NET / Solr.NET but it look to me that a solution for this would be to use generic types:

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

interface ISearchService<TEntity>
{
    SearchResult<TEntity> Search(string text);
    void Index<TEntity>(TEntity entity);
    ...
}
share|improve this answer
1  
The question says the type of the search result is different from the type of the normal entity. –  svick Jul 22 '13 at 19:00

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.