Multilingual Taxonomy Search   

Tags: SharePoint 2010, Search, Taxonomy
Technorati Tags: , ,

 

Issue

 

One of the issues I came across search was the problem with multilingual taxonomy.

 

When I was searching for a document with a certain taxonomy term I could find the document in the default language but not in a other language.

 

 

Explanation

 

If you use taxonomy on an item or document it will save the taxonomy like this => 1;#”Default label”|Taxonomy Guid.

Example: I create an item and choose the taxonomy value “Monday” it will be saved like this => 1;”Monday”|D5BAD544-9A7E-4936-AD24-9E75D2E0FC5B

When I switch the language to french and create an item and choose “Lundi” it will be saved like this => 1;”Monday”|D5BAD544-9A7E-4936-AD24-9E75D2E0FC5B

So when we search for “monday” we can find the item we created but when we search for “lundi” we don’t find the item because it isn’t saved with lundi but with “Monday”.

A fix

 

So a possible fix is to extend the Core results webpart. So when we search for a taxonomy we are searching for the id and not for the name.

 

Follow these examples if you don’t have multilingual terms or if the terms are not mapped.

 

- Creating multilingual terms

Creating multilingual terms

 

- Adding the terms to the mapped properties

Mapping taxonomy to search properties

 

 

1) Create a new empty SharePoint project and name it TaxonomySearchResults.

 

2) Create a new webpart not a visual webpart. Name it TaxonomySearchResultsWebPart.

WebPart

 

3)Add the assembly Microsoft.SharePoint.Search  found in the ISAPI map => C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI

 

4) inherit from the CoreResultsWebPart.

public class TaxonomySearchResultsWebPart : CoreResultsWebPart
{

 

5) Extend the init class

public TaxonomySearchResultsWebPart()
    : base() { }

 

6) Override the onload method

protected override void OnLoad(EventArgs e)
{
     base.OnLoad(e);
 
     //base.xmlResponseDoc has to be null or else the query is already excuted
     if (base.xmlResponseDoc == null)
     {
            SetAdditionalQueryTerm();
      }
}

7) Create the method SetAdditionalQueryTerm

        private void SetAdditionalQueryTerm()
        {
            try
            {
                //get the queryObject
                object queryObject = HttpContext.Current.Items["WSSSRHDC_0"];
 
                Type valType = queryObject.GetType();
 
                //get the full text query
                PropertyInfo fullTextQueryProp = valType.GetProperty("FullTextQuery", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
 
                //get the query
                string query = (string)fullTextQueryProp.GetValue(queryObject, null);
 
                if (string.IsNullOrEmpty(query))
                {
                    // get the keywords that the query is searching for
                    PropertyInfo keywordQueryProp = valType.GetProperty("KeywordQuery", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
 
                    //get the query with the keywords
                    query = (String)keywordQueryProp.GetValue(queryObject, null);
 
                    //create the new query
                    string newQuery = SetQuery(query);
 
                    //set the new query
                    keywordQueryProp.SetValue(queryObject, newQuery, null);
                }
 
            }
            catch (Exception ex)
            {
               
            }
        }

 

8) Create the method SetQuery

private string SetQuery(string query)
{
 
    //split the search keywords 
      string[] words = query.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
 
     //string oldword = string.Empty;
 
     string id = string.Empty;
 
     //the new query that's going to be send back
            string newQuery = query;
 
    //loop each word to get the id of the taxonomy term
     foreach (string word in words)
     {
          id = GetTermId(word);
              
          newQuery.Replace(word, id);
       }
 
       return newQuery;
 
}

 

9) Create the method GetTermID

private string GetTermId(string termName, string groupName)
{
    string result = termName;
 
    //create the taxonomy session
     TaxonomySession session = new TaxonomySession(SPContext.Current.Site, false);
 
     //search the taxonomy term based on the language that sharepoint is currently in
     var terms = session.GetTermsInWorkingLocale(termName, false, StringMatchOption.ExactMatch, 1, true, true);
 
      //send the first term we found back
       if (terms.Count > 0)
       {
            result = terms[0].Id.ToString();
        }
 
        //if no term was found send back the original name
        return result;
        }

 

10) Deploy this solution and add the webpart to the search result page of SharePoint

 

Later this week the webpart can be downloaded at my companies codeplex site: Ventigrate codeplex

 
Posted by  Gilissen Timmy  on  8/1/2011
2  Comments  |  Trackback Url  | 0  Links to this post | Bookmark this post with:        
 

Links to this post

Comments


Rahul  commented on  Sunday, October 2, 2011  9:15 PM 
Thanks alot,even I am facing the same problem.But unfortunately i am not getting any value for queryobject in this example i.e. object queryObject = HttpContext.Current.Items["WSSSRHDC_0"];
I am using SP 2010


Timmy  commented on  Tuesday, December 13, 2011  3:39 PM 
Hi,

Sorry for the late reply but did you had a look at this post

http://www.moss2007.be/blogs/timmy/archive/2011/08/08/improved-core-result-webpart.aspx

Name *:
URL:
Email:
Comments:


CAPTCHA Image Validation