Documentation

Ucommerce includes full API reference documentation and lots of helpful articles to help you build your e-commerce site as effortlessly as possible.

Topics Payment Providers
v7.18

Enabling case insensitive wildcard search for Lucene

By default, Lucene does not offer case insensitive wildcard search, but fortunately you can work around this by following the guide below.

To make this work, you would create a custom adorner, as well as a custom field on your index definition. The adorner will then index the fields of your choosing into the new custom field as lower-cased strings. You can then add the custom field to your wildcard search. Further information can be found below. Read more about adorners here.

First, we add the new field to out index definition as show below, read more about Index Definitions here.

    
    this.Field(p => p["wildcard"], typeof(string));
    

The name of the field can be any name of your choosing, as long as you do not have another field with the same name in the index.

When choosing which fields to enable case insensitive search on, be aware that Lucene limits the length of indexed fields to 32766 bytes!

We then create our adorner, in this example, we will be indexing properties Displayname as well as Name to be used for our case insensitive wildcard search.

    public class WildcardAdorner : IAdorn<Ucommerce.Search.Models.Product>
    {
        public void Adorn(IEnumerable<Ucommerce.Search.Models.Product> items)
        {
        }
    
        public void Adorn(IEnumerable<Ucommerce.Search.Models.Product> localizedItems, CultureInfo culture)
        {
            foreach (Ucommerce.Search.Models.Product product in localizedItems)
            {
                try
                {
                    if(!string.IsNullOrWhiteSpace(product.DisplayName))
                        product["wildcard"] = $"{product.DisplayName.ToLower()}, custom_field_value";
                    else if(!string.IsNullOrWhiteSpace(product.Name))
                        product["wildcard"] = $"{product.Name.ToLower()}, custom_field_value";
                }
                catch (Exception e)
                {
                    if (product == null)
                    {
                        throw;
                    }
    
                    var message = string.Format(SearchConstants.FAILED_PRODUCT_INFO, product.Guid);
    
                    throw new ProductSlugAdornerException(message, e);
                }
            }
        }
    }
    

After re-indexing, we can now use our new wildcard field for case insensitive wildcard search. An example of this can be seen below.

    
    var products = ProductIndex.Find()
        .Where(p => p.VariantSku == null &&
            (
                p.Sku.Contains(keyword)
                || p.Name.Contains(keyword)
                || p.DisplayName == Match.FullText(keyword)
                || p.ShortDescription == Match.FullText(keyword)
                || p.LongDescription == Match.FullText(keyword)
                || p["wildcard"] == Match.Wildcard(keyword.ToLower())
            )
        ).ToList();