Search code examples
c#luceneumbracoexamine

Using Examine Manager to search content


This is the first time I have used Examine - So far this is working, results variable have the correct data, however what I want to do is add the searchTerm variable I want to search all fields of all nodes that currently are returned in results

Any Ideas? - Thanks in advance.

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

IBooleanOperation query = criteria.NodeTypeAlias("level1")
.Or().NodeTypeAlias("level2")
.Or().NodeTypeAlias("simpleTextPage")
.Or().NodeTypeAlias("contactPage")
.Or().NodeTypeAlias("Locationfinder");

string searchTerm = "Term to Search for here";

var results = searchEngine.Search(query.Compile());

Solution

  • There are two parts to this answer. Firstly you need to specify which field(s) you wish to search against:

    .Or().Field("bodyText", searchTerm)

    This makes the assumption that your pages have a bodyText property. You can append additional fields onto this to search against other properties, e.g. name, introText etc.

    Secondly, if you want to search across all fields, you will need to create a field that contains all the text content from the page being indexed. You need to:

    1. Create an Umbraco event that implements IApplicationEventHandler;
    2. Add a handler for gathering node data:

      void OnApplicationStarted(UmbracoApplicationBase app, ApplicationContext ctx)
      {
          ExamineManager.Instance
                        .IndexProviderCollection["ExternalIndexer"]
                        .GatheringNodeData += OnGatheringNodeData;
      }
      
    3. Create your combined field:

      protected void OnGatheringNodeData(object sender, IndexingNodeDataEventArgs e)
      {
          var builder = new StringBuilder();
          foreach (var entry in e.Fields)
          {
              builder.AppendFormat("{0}, ", entry.Value);
          }
      
          e.Fields.Add("combinedText", builder.ToString());
      }
      
      1. Change your search to be .Or().Field("combinedText", searchTerm);

    Now each time a page is published, it will combine all fields into one so that they can be search upon in the way you wish.

    However, personally, I would advise you select specific fields to combine as there is rarely any need to combine all. This is usually a sign that there is little consistency in your document types. I always use common aliases throughout all my doc types for reasons like this, e.g. bodyText, introText, summaryText etc. This way if needed I could filter out the fields ending in "Text" or have my aliases as static strings.