0

This is my code for searching a data in the specified index:

using (var context = ContentSearchManager.GetIndex(Common.Constants.IndexNames.PlotTreeIndexName).CreateSearchContext())
{
    var plotTreeQuerable = context.GetQueryable<UserPlottedTreeSearchResultItem>()
        .Where(m => m.LatestVersion)
        .Where(m => m.TemplateId == new Sitecore.Data.ID(Common.Constants.TemplateIDs.UserPlottedTreePageTemplateId));

    List<UserPlottedTreeSearchResultItem> results = new List<UserPlottedTreeSearchResultItem>();

    if (!string.IsNullOrEmpty(searchTerm))
    {
        var predicate = PredicateBuilder.True<UserPlottedTreeSearchResultItem>();
        if (typeOfSearch.ToUpper() == Constants.SearchTerm.EmailAddress.ToUpper())
        {
            predicate = predicate.Or(m => m.PersonEmail.Equals(searchTerm));
        }
        else if (typeOfSearch.Equals(Constants.SearchTerm.NameOfThePerson, StringComparison.OrdinalIgnoreCase))
        {
            predicate = predicate.Or(m => m.PersonName.Equals(searchTerm, StringComparison.InvariantCultureIgnoreCase));
        }
        else
        {
            foreach (var t in searchTerm.Trim().Split(' '))
            {
                predicate = predicate.Or(m => m.PersonName.Contains(t) || m.PersonEmail.Contains(t));
            }
        }
        plotTreeQuerable = plotTreeQuerable.Where(predicate);
    }
    if (plotTreeQuerable.Count() > 0)
    {
        results = plotTreeQuerable.ToList();
        return results;
    }
}

The string in m.PersonEmail should be case-insensitive. I tried the following code with their respective results:

test search value: test.Val

sample dataset/list:

test.val
test.Val
Test.val
TEST.VAL
  1. predicate = predicate.Or(m => m.PersonEmail.Equals(searchTerm, StringComparison.OrdinalIgnoreCase))

Result: only returns test.Val

  1. predicate = predicate.Or(m => m.PersonEmail.Contains(searchTerm))

same result: (returns test.Val)

Any reason as to why my code doesn't work? it should return all data from the dataset/list. First code doesn't seem to respect the StringComparison.OrdinalIgnoreCase

4 Answers 4

1

Option 1

You should add a new filter solr.LowerCaseFilterFactory to convert everything to a lowercase , this should apply to index and query.

Schema.xml

<field name="Name" type="text_general" indexed="true" stored="true"/>

Where text_general type

<fieldType name="text_general" class="solr.TextField" omitNorms="false" positionIncrementGap="100" multiValued="true">
  <analyzer type="index">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
  </analyzer>
  <analyzer type="query">
    <tokenizer class="solr.WhitespaceTokenizerFactory"/>
    <filter class="solr.StopFilterFactory" words="stopwords.txt" ignoreCase="true"/>
    <filter class="solr.LowerCaseFilterFactory"/>
    tokenizerFactory="solr.WhitespaceTokenizerFactory"/>
  </analyzer>
</fieldType>

Option 2

The second option is that you can create a computed field for PersonEmail which will convert the value to lowercase and then you can match PersonEmail value to search value in lowercase.

In this link, it is mentioned how we can create the computed fields.

Below are the sample code as well:

public class EmailLowercase : IComputedIndexField
{
    public object ComputeFieldValue(IIndexable indexable)
    {
        Item item = (Item) (indexable as SitecoreIndexableItem);
        // null check on item
            if (item == null)
            {
                return null;
            }
        
       //retutn value=Get PersonEmail field and return in lower case.
    }

    public string FieldName { get; set; }

    public string ReturnType { get; set; }
}

and add below code in your solr config file

<fields hint="raw:AddComputedIndexField">
    <field fieldName="EmailLowercase">Name.ComputedFields.EmailLowercase, Name</field>
</fields>
6
  • hi, where can i find this?
    – Christian
    Commented Mar 9, 2022 at 12:41
  • your-solr-instance\server\solr\configsets_default\conf\managed-schema Commented Mar 9, 2022 at 13:27
  • sorry im quite new. is solr automatically installed when you setup a sitecore proj? cuz i don't recall having this in my local machine
    – Christian
    Commented Mar 9, 2022 at 13:48
  • @Christian mostly it's in C: drive where you can find your SOLR directory named Solr or SOLR-{Version} folder. Commented Mar 9, 2022 at 14:18
  • hmm but for the index config files, i think it's using lucene. i found this tag under one of the fieldnames <analyzer type="Sitecore.ContentSearch.LuceneProvider.Analyzers.LowerCaseKeywordAnalyzer" /> is it the same from what you are trying to achieve?
    – Christian
    Commented Mar 9, 2022 at 16:13
1

The default index field type in Solr is tokenized which means that it will split up the string in your index. So, we need to make that index type to be untokenized and index field needs to be treated as a regular string but not tokenized index.

<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/" xmlns:role="http://www.sitecore.net/xmlconfig/role/" xmlns:search="http://www.sitecore.net/xmlconfig/search/">
  <sitecore role:require="Standalone or ContentManagement or ContentDelivery">
    <contentSearch>
      <indexConfigurations>
        <defaultSolrIndexConfiguration type="Sitecore.ContentSearch.SolrProvider.SolrIndexConfiguration, Sitecore.ContentSearch.SolrProvider" search:require="solr">
          <documentOptions type="Sitecore.ContentSearch.SolrProvider.SolrDocumentBuilderOptions, Sitecore.ContentSearch.SolrProvider">
          <fields hint="raw:AddComputedIndexField">
          </fields>
          </documentOptions>
          <fieldMap>
            <fieldNames>
              <field fieldName="email" returnType="string"   storageType="YES" indexType="UNTOKENIZED" vectorType="NO" boost="1f" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider" />
          </fieldNames>
          </fieldMap>
        </defaultSolrIndexConfiguration>
      </indexConfigurations>
    </contentSearch>
  </sitecore>
</configuration>
0

The idea with ContentSearch LINQ provider is to have readable queries that are serialized into Solr queries. Therefore all the native C# logic cannot be understood by Solr. Look in the search.log and verify what your query actually ends up being.

It's quite easy to make such mistakes with the ContentSearch LINQ implementation, so many people find it better to use the native SolrNet API instead, ensuring the query being performed is the expected one. However that requires a bit more knowledge about Solr.

In your example, it basically boils down to the field you've indexed and whether Solr treats is as case sensitive or not. A good practice is to ensure the content is indexed in a way that suits the queries you need to perform.

2
  • i see. yes, the content is indexed but it still doesn't work
    – Christian
    Commented Mar 9, 2022 at 12:21
  • Then it's probably something about the field types/configuration in Solr, like if you're using "text" or "string" field types. Try making the Solr query native in the Solr Query UI. Once you get the correct response there, you can mimic that in your code.
    – mikaelnet
    Commented Mar 9, 2022 at 13:23
0

I managed to make it work by making the index

indexType="TOKENIZED"

<field fieldName="Email" storageType="YES" indexType="TOKENIZED" vectorType="NO" boost="1f" type="System.String" settingType="Sitecore.ContentSearch.LuceneProvider.LuceneSearchFieldConfiguration, Sitecore.ContentSearch.LuceneProvider" />

1
  • Which version of Sitecore are you using ?
    – Ashish
    Commented Mar 10, 2022 at 8:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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