Thursday, October 23, 2014

Using SolrNet (0.4.0.2002) and AutoMapper...

If you're using Solr and you prefer to use .Net, then SolrNet is a great way to go. It's easy to use whether your indexing documents, querying for documents, or both.

Here is an example using Solr 4.10.1, SolrNet 0.4.0.2002, and AutoMapper

I installed Solr 4.10.1, and used the default example "collection1" core for this example. 

I created a POCO for the example and cleverly named it SolrDoc. I only bothered with a few of the values that are defined in the schema used in the collection1 core:

public class SolrDoc
{
    [SolrUniqueKey("id")]
    public string Id { get; set; }

    [SolrField("sku")]
    public string Sku { get; set; }

    [SolrField("name")]
    public string Name { get; set; }

    [SolrField("cat")]
    public List Categories { get; set; }

}

And created another POCO to act as a domain object (only to show how you can map from the Solr document), and named it SolrItem:


public class SolrItem
{
    public string Identifier { get; set; }
    public string Sku { get; set; }
    public string Name { get; set; }
    public List Cats { get; set; }
    public override string ToString()
    {
        var sb = new StringBuilder(
                 string.Format("Identifier: {0}, SKU: {1}, Name: {2}", 
                                Identifier, Sku, Name));
        if (Cats != null)
        {
            sb.Append("\nCategories:");
            foreach (var category in Cats)
            {
                sb.Append(string.Format("\n\t{0}", category));
            }
        }
        return sb.ToString();
    }
}

The following code isn't necessary for use with Solr, but it is necessary for creating the AutoMapper mapping between SolrDoc and SolrItem. Perhaps you won't need to map your Solr documents to some other contract object, but if you do have that need then AutoMapper is easy to use. 

One way that AutoMapper can be used is to map between public and private views of data. As an example, you might have an API that allows users to view either detailed or summary user info. Your private model of the user data can have all user information and you can have AutoMapper map the user info to summary or detailed user info objects that are returned to the user. I included the AutoMapper usage as a way to show that you can easily get the Solr documents and then map them to whatever form you might need.

Here is the code that configures AutoMapper's source to destination mapping.


public static void InitMappings()
{
    Mapper.CreateMap()
        .ForMember(dest => dest.Cats, opt => opt.MapFrom(src => src.Categories))
        .ForMember(dest => dest.Identifier, opt => opt.MapFrom(src => src.Id));

}

Here is the code that indexes a document into Solr, and then queries Solr for all documents. The foreach loop is where the SolrDoc is mapped to a SolrItem.


static void Main(string[] args)
{
    // Set up the automapper mapping
    InitMappings();
        
    // Point to the Solr server that was started using the Solr example
    // of "java -jar start.jar"
    Startup.Init<SolrDoc>("http://localhost:8983/solr/collection1");

    // Get an instance of the Solr service that will map Solr documents to 
    // a POCO of type SolrDoc
    var solr = ServiceLocator.Current.GetInstance<ISolrOperations<SolrDoc>>();

    // Create a SolrDoc to index into Solr
    var doc = new SolrDoc
    {
        Id = Guid.NewGuid().ToString(),
        Name = "Some SolrDoc",
        Sku = "Some_Sku",
        Categories = new List {"cat1", "cat2", "cat3"}
    };

    // Index and commit the doc
    solr.Add(doc);
    solr.Commit();

    // Query for all documents
    var results = solr.Query(new SolrQueryByField("id", "*"));

    // Loop through all results
    foreach (var result in results)
    {
        var solrItem = Mapper.Map<SolrItem>(result);
        Console.WriteLine(solrItem);
    }
}

No comments:

Post a Comment