Issue filtering Solr query with ContentSearch API

I'm trying to use the ContentSearch API to apply a 'Where' clause to my query:

using (var context = SearchIndex.CreateSearchContext())
{
  var query = context.GetQueryable<CustomSearchResultItem>();

  query = query.Where(x => x["topics"] == "some value");

}

This produces an error in the Search logs, as follows:

"ERROR Solr Error : ["undefined field topics"]"

At first, I thought this is because I need to pass in the Solr field name (in this case "topics_sm").  However, doing this:

query = query.Where(x => x["topics_sm"] == "some value");

result in the same error in the logs.

I even tried the field name "topics_sm_sm".  But the Solr query always tries to filter by "topics".  Filtering and faceting works fine when using properties of my CustomSearchResultItem but I need to be able to use the index notation.  Why is the field name being manipulated and can I work around this?  This only appears to be an issue when the search provider is Solr.  I have not encountered an issue when Lucene is the provider.

  • Hi,

    You can check your Sitecore log ( search log part ) to get the exact Solr query which run on your system.
    Copy&paste it to the solr web layout (site:portnumber/solr/ ) and use it.
    You can check the indexed fields and other information on that web page.

    If you want create multiple predicate use PredicateBuilder:
    www.sitecore.net/.../sitecore-7-predicate-builder.aspx

    Best regards,
    Chris
  • Please look at the exact field name through Solr interface. If it is "topics_sm" in the Solr interface, but in code it is trying to filter by "topics", that means the field is definitely getting modified that way, somewhere in the code. I hope only debugging can help you more.
  • In reply to Amrita Shukla:

    Hi Amrita,

    Yes, the Solr field name is definitely "topics_sm". And the resulting Solr query tries to query the field name "topics" which is invalid. I tracked this back to the SolrFieldNameTranslator class. It is explicitly removing the the suffixes that Solr applies to all field names. However, I don't understand why this is happening. This is causing all filtering/faceting done via the indexer notation to result in invalid queries.
  • Hard to say what the exact problem is, but if you haven't already grab the exact query that get's built out in your Search.log located in your data folder. That should be the query that it actually runs on Solr. Then go to the solr query interface on your solr instance and try running that query. Maybe you are executing this on the wrong context? Maybe you'll notice something in the syntax? Remove the where class altogether and verify that the topics filed is on the documents in the index. I ran into something similar and ended up creating a class that inherits from SearchResultItem and used that class with my query, which solved my problem.

    public class CustomResultItem : SearchResultItem
    {
    [IndexField("topics")]
    public string Topics {get;set;}
    }

    Hope some of that helps!
  • If you use POCO entities like what Jonathan suggested, then the LINQ provider should do the necessary mapping. However if you are using the field name as a string (like in your query), you either need to:

    1) Specify its full name like "topics_sm" - I know you said that it did not work. You have used "_sm", which is typically used for string collection, string array or guid collection in Solr. For strings, it is typically "_s". Are you sure you are using the right field name?

    OR

    2) Have it mapped to the specific type so that LINQ knows how to treat it

    <fieldNames hint="raw:AddFieldByFieldName">

        <fieldType fieldName="topics"     returnType="string" />

    </fieldNames>

  • Hi,

    I have faced the same issue and found the reason for the same. (Replying this as it may help some other developer facing similar issue)

     

    Your items has a field named "topics", it will be indexed.

    But it will be skipped if the value of "topics" is null/blank for any item.

    Like if this is a multi list or drop link and no value is selected for "topics" for item named "ABC", "ABC" will not have any field named "topics" in search index and your query will fail.

    to avoid this, you have below options

    1. You may need to add a computed field
    2. Instead of .where, use a foreach loop and get the value (code below)
    3. Sitecore will always have the field so use Sitecore in query. 
      Not recommended for large amount of results. 
      var query = context.GetQueryable<SearchResultItem>();
      query = query.Where(x => x.GetItem().Fields["topics"].Value == "some value");



    For option 2: 

    Inside for each if you check the key exist or not then you can avoid the exception.

                   using (var context = searchIndex.CreateSearchContext())

                   {

                       var query = context.GetQueryable<SearchResultItem>();

                       List<SearchResultItem> resultsItems = new List<SearchResultItem>();

                       foreach (var item in query)

                       {

                           if (item.Fields.ContainsKey("topics"))

                           {

                               if (item.Fields["topics"] == "Value to check")

                               {

                                   resultsItems.Add(item);

                                   // or other task to complete...

                               }

                           }

                       }

                       return resultsItems;

                   }