Search code examples
solrsolrnet

Using score field with SolrNet


I'm using SolrNet and have a problem where the score field is conflicting with documents being added or updated in the index.

The class representing my documents looks something like this

class MyDoc
{
    [SolrUniqueKey("doc_id")]
    public string DocId { get; set; }

    [SolrField("foo")]
    public string Foo { get; set; }

    [SolrField("bar")]
    public string Bar { get; set; }

    [SolrField("score")]
    public double Score { get; set; }
}

In the query being issued to Solr, I've added the 'score' field to the fl parameter, and the score value is returned and set correctly on this class. However, when adding or updating documents, I'm getting an error about the score field not existing in my index, which it doesn't, and shouldn't as this is a dynamic field.

The code doing the add/update is fairly simple:

Startup.Container.GetInstance<ISolrOperations<MyDoc>>().Add(doc);

It looks like I need the score property to be ignored by SolrNet (or Solr) when adding or updating documents, and only use it when retrieving documents.

Is there any way to achieve this?


Solution

  • I have accomplished this by having two separate classes. One that maps to documents being retrieved from the index as search results and another class that is used to add items to the index. So in this scenario you could do the following:

     class MyDoc
     {
          [SolrUniqueKey("doc_id")]
          public string DocId { get; set; }
    
          [SolrField("foo")]
          public string Foo { get; set; }
    
          [SolrField("bar")]
          public string Bar { get; set; }
     }
    
    
     class MyDocResult
     {
          [SolrUniqueKey("doc_id")]
          public string DocId { get; set; }
    
          [SolrField("foo")]
          public string Foo { get; set; }
    
          [SolrField("bar")]
          public string Bar { get; set; }
    
          [SolrField("score")]
          public double Score { get; set; }
     }
    

    Be sure you initialize both classes pointing to the same solr url. Startup.Init("http://localhost:8983/solr"); Startup.Init("http://localhost:8983/solr");

    Then you can add with:

      ServiceLocator.Current.GetInstance<ISolrOperations<MyDoc>>().Add(doc);
    

    And Query with:

      var solr ServiceLocator.Current.GetInstance<ISolrOperations<MyDocResult>>();
      var results = solr.Query("foo bar");
    

    You could also look into using the Dynamic or Fully Loose Mapping options for SolrNet if you do not want to create two separate classes.