X
Closing this message and/or accessing our website tells us you are happy to receive all cookies on the ClearPeople website.
However, if you would like to, you can change your cookies settings at any time.
Recently I have been having issues while trying to send really long queries to Solr from Sitecore.

Sometimes my problem was Solr rejecting the request, other .Net itself complaining about the length of the uri.


Error: Invalid URI: The Uri string is too long.


The remote server returned an error: (414) Request-URI Too Long


After considering setting higher values on Solr configuration, the long-term solution seems to be to use the post method to send the request. This is now part of Solrnet, the .Net client used by Sitecore.


I got in contact with Sitecore, but while waiting I came up with this "solution":


Create a new SolrStartUp class inheriting from the default one

publicclassPostSolrStartUpDefaultSolrStartUp

    {
        protected override ISolrConnection CreateConnection(string serverUrl)
        {
            SolrConnection basecon = new SolrConnection(serverUrl) { Timeout = SolrContentSearchManager.ConnectionTimeout };
            
 
            FieldInfo field = typeof(DefaultSolrStartUp).GetField("solrCache"BindingFlags.Instance | BindingFlags.NonPublic);
            var basecache = field.GetValue(this);
            if (basecache != null)
            {
                basecon.Cache = (ISolrCache)basecache;
            }
            PostSolrConnection solrConnection = new PostSolrConnection(basecon, serverUrl);
            return solrConnection;
        }
    }


Create a new Sitecore Initializer

public class InitializeSolrProvider
    {
        public InitializeSolrProvider()
        {
        }

        public void Process(PipelineArgs args)
        {
            if (!SolrContentSearchManager.IsEnabled)
            {
                return;
            }
            if (!IntegrationHelper.IsSolrConfigured())
            {
                (new PostSolrStartUp()).Initialize();
                return;
            }
            IntegrationHelper.ReportDoubleSolrConfigurationAttempt(this.GetType());
        }
    }


Replace the default initializer with yours

  <sitecore>
    <pipelines>
      <initialize>
        <processor type="ClearPeople.Sitecore.ContentSearch.SolrProvider.InitializeSolrProvider, ClearPeople.Sitecore"
         patch:instead="processor[@type='Sitecore.ContentSearch.SolrProvider.Pipelines.Loader.InitializeSolrProvider,
 Sitecore.ContentSearch.SolrProvider']" />
      </initialize>
    </pipelines>
  </sitecore>


That's it, with these changes my Sitecore instance communicates with Solr using post.


Tricks:

  • You must add a reference to SitecoreContentSearch.SolrProvider
  • You need to reference Solrnet 4.0.2.002 I couldn't find a valid version on Nuget, as the 4.0.2 (beta) doesn't have the new PostSolrConnection class we need, So I had to fall back to the one provided with Sitecore.

Side effects found so far:

  • With get, when Solr returns some errors due to invalid field names, the error could be found in the search log, now it appears in the general log

Disclaimer: Of course, this is some PoC, and you must test and improve it yourself before using it in a real project.


Update 09/06/2017: Sitecore has reported this as a bug and has a patch available that let you configure which method to use: GET or POST. The reference number for this patch is 166359 The patch uses the same solution as this code to connect to Solr via POST with the PostSolrStartUp class. This is how they introduced the configuration bit in the InitializeSolrProvider:


public void Process(PipelineArgs args)
        {
            if (SolrContentSearchManager.get_IsEnabled())
            {
                string setting = Settings.GetSetting("ContentSearch.RequestMethod");
                if (IntegrationHelper.IsSolrConfigured())
                {
                    IntegrationHelper.ReportDoubleSolrConfigurationAttempt(this.GetType());
                    return;
                }
                if (!StringExtensions.IsNullOrEmpty(setting) && setting.ToLower() == "post")
                {
                    (new PostSolrStartUp()).Initialize();
                    return;
                }
                (new DefaultSolrStartUp()).Initialize();
            }
        }

Author bio

Vicent Galiana
Vicent Galiana
Solutions Architect
Putting blocks together to make things easier, creating those missing clever parts which make it possible. That's my passion, that's my hobby, that's my job. It's about keeping up to date with current tools, and figuring out how to glue them together to solve client's challenges.

Comments


comments powered by Disqus

Related Articles

Sign up to our Newsletter

Every now and then, we'd like to send you information that delivers, develops and promotes our products and services that are relevant to you. Submitting your details tells us that you're OK with this and you also agree to our Privacy & Cookies policy. You can, of course, opt out of these communications at any time.