umbracolucene.netumbraco7umbraco6umbraco-blog

Umbraco - Using Examine to search Umbraco.Tags


I have a umbraco doctype with a field that is of type Umbraco.Tags.

Using examine to search the field like this:

var searchEngine = ExamineManager.Instance.SearchProviderCollection["ExternalSearcher"];
            var searchCriteria = searchEngine.CreateSearchCriteria(BooleanOperation.Or);

            var query = searchCriteria.Field("title", searchTerm)
            .Or().Field("topicTags", searchTerm).Compile();
var results = searchEngine.Search(query);

I know for a fact that the value is inside topicTags, but it result is 0...

Any ideas?

Update: It turns out the reason why no results are found is because the Umbraco.Tags datatype stores data like this: tag1,tag2,tag3 with no spaces, so tag1 is not in the index, I would have to search for "tag1,tag2,tag3" to get a hit.

Looks like I might have to high-jack the Examine index event and change the way the data is indexed.

These is a built in umbraco data type, surely there is a way to search it.


Solution

  • Yes your right, the reason why I was getting 0 was the tags are stored like this:

    tag1,tag2,tag3. 
    

    With no spaces.

    So tag1,tag2,tag3 would result in a hit, but tag1 wouldn't.

    The solution was to hook in to the umbraco publish event and change the way that field is indexed. Solution:

     public class ExamineEvents : ApplicationStartupHandler
    {
    public ExamineEvents()
    {
        ExamineManager.Instance.IndexProviderCollection["ExternalIndexer"].GatheringNodeData +=
            ExamineEvents_GatheringNodeData;
    }
    
    
    private void ExamineEvents_GatheringNodeData(object sender, IndexingNodeDataEventArgs e)
    {
                    if (e.IndexType != IndexTypes.Content) return;
    
        // Node picker values are stored as csv which will not be indexed properly 
        // We need to write the values back into the index without commas so they are indexed correctly
        var fields = e.Fields;
        var searchableFields = new Dictionary<string, string>();
        foreach (var field in fields)
        {
            switch (field.Key)
            {
                case "topicTags":
    
                    var searchableFieldKey = "topicTagsIndexed";
                    var searchableFieldValue = field.Value.Replace(',', ' ');
                    if (!string.IsNullOrEmpty(searchableFieldValue))
                    {
                        searchableFields.Add(searchableFieldKey, searchableFieldValue);
                    }
                    break;
            }
        }
    
        foreach (var fld in searchableFields)
        {
            e.Fields.Add(fld.Key, fld.Value);
        }
    }
    

    Then when you create your search query you search in the field topicTagsIndexed

    SearchCriteria.Field("pagetitle", searchTerm).Or().Field("topicTagsIndexed", searchTerm).Compile();
    

    Hope this helps someone else.