Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

I am developing a Web Part for SharePoint 2010 that uses FullTextSqlQuery to perform People Search using a CONTAINS clause on the PastProjects managed property.

I am not getting any results back. Similar queries for other managed properties do return data (Responsibility, Skills, Interests), so my problem seems to be specific to the PastProjects managed property. I know there are results in the index, since the out of the box people search does return my current profile when I search for an item that appears in my "Past projects" user profile property (which also proves the index is up to date).

I read this article that says you need to ensure the managed properties have FullTextQueriable set to true. I found out that PastProjects does not have this, but since the out of the box People Search does return the expected results I would say I should be able to achieve my goal without setting FullTextQueriable to true on PastProjects.

I have included some Web Part code below which hopefully can be used to reproduce the problem. I would appreciate it if someone could run this code on their dev environment and let me know what the Web Part has rendered.

Before you run the web part, make sure you have your following user profile properties populated with multiple values: Past projects, Skills, Interests, Ask Me About.

Also make sure your index is up to date, and confirm your user is being returned by the out of the box people search when you search for any of the keywords you entered in your user profile (including values in Past Projects).

Thank you!

using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.Office.Server;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.Office.Server.Search.Administration;
using System.Collections.Specialized;
using Microsoft.SharePoint.Administration;
using System.Collections;
using System.Data;
using Microsoft.Office.Server.Search.Query;
using System.Text;

namespace SampleCode
{
    [ToolboxItemAttribute(false)]
    public class SearchDemoWebPart1 : WebPart
    {
        protected Literal literalMessage;

        protected override void CreateChildControls()
        {
            this.literalMessage = new Literal();
            this.literalMessage.ID = "literalMessage";
            this.Controls.Add(this.literalMessage);
        }

        protected override void  OnLoad(EventArgs e)
        {
            base.OnLoad(e);

            string searchProxyName = "Search Default SA"; // make sure this matches the name of your SharePoint Search Application

            UserProfileManager manager = new UserProfileManager(SPServiceContext.Current);

            UserProfile profile = manager.GetUserProfile(false);

            SearchQueryAndSiteSettingsServiceProxy settingsProxy = SPFarm.Local.ServiceProxies.GetValue<SearchQueryAndSiteSettingsServiceProxy>();

            SearchServiceApplicationProxy searchProxy = settingsProxy.ApplicationProxies.GetValue<SearchServiceApplicationProxy>(searchProxyName);

            NameValueCollection pairs = new NameValueCollection();
            pairs.Add("SPS-Responsibility", "Responsibility");
            pairs.Add("SPS-PastProjects",   "PastProjects");
            pairs.Add("SPS-Skills",         "Skills");
            pairs.Add("SPS-Interests",      "Interests");

            StringBuilder messages = new StringBuilder();

            foreach (string key in pairs.AllKeys)
            {
                string profilePropertyName = key;
                string managedPropertyName = pairs[key];

                this.ProcessUserProfileProperty(searchProxy, profile, profilePropertyName, managedPropertyName, messages);
            }

            this.EnsureChildControls();

            this.literalMessage.Text = messages.ToString();
        }

        public void ProcessUserProfileProperty(SearchServiceApplicationProxy searchProxy, UserProfile profile, string profilePropertyName, string managedPropertyName, StringBuilder messages)
        {
            IEnumerator allValues = profile[profilePropertyName].GetEnumerator();

            while (allValues.MoveNext())
            {
                string keyword = allValues.Current.ToString();

                DataTable resultsDataTable = new DataTable();

                FullTextSqlQuery sqlQuery = new FullTextSqlQuery(searchProxy);

                StringBuilder queryText = new StringBuilder();

                sqlQuery.QueryText = String.Format(@"SELECT Title, AccountName, {0} FROM SCOPE() WHERE CONTAINS({0}, '{1}') AND (""Scope""='People')", managedPropertyName, keyword);
                sqlQuery.ResultsProvider = SearchProvider.Default;
                sqlQuery.ResultTypes = ResultType.RelevantResults;

                ResultTableCollection resultsTableCollection = sqlQuery.Execute();

                using (ResultTable searchResultsTable = resultsTableCollection[ResultType.RelevantResults])
                {
                    resultsDataTable.TableName = keyword;
                    resultsDataTable.Load(searchResultsTable, LoadOption.OverwriteChanges);
                }

                string color = resultsDataTable.Rows.Count == 0 ? "red" : "green";

                messages.AppendFormat(@"<div style=""color: {3}"">Found {0} result(s) for '{1}' in Managed Property '{2}'.</div>", resultsDataTable.Rows.Count, keyword, managedPropertyName, color);
            }
        }
    }
}
share|improve this question

2 Answers 2

up vote 4 down vote accepted

Try using a KeywordQuery and setting the RankingModeID to "D9BFB1A1-9036-4627-83B2-BBD9983AC8A1"

This PowerShell code works for me

Add-PSSnapin Microsoft.SharePoint.PowerShell

$site = get-spsite "http://localhost"
$kq = new-object Microsoft.Office.Server.Search.Query.KeywordQuery($site)

$kq.ResultTypes= [Microsoft.Office.Server.Search.Query.ResultType]::RelevantResults
$kq.RankingModelId = "D9BFB1A1-9036-4627-83B2-BBD9983AC8A1"
$kq.QueryText = 'gamma'
$kq.HiddenConstraints = 'scope:"People"'
$res = $kq.Execute()

$table = new-object System.Data.DataTable
$table.Load($res[$kq.ResultTypes],[System.Data.LoadOption]::OverwriteChanges)

echo $table

The full list of ranking models can be found with this powershell.

Get-SPEnterpriseSearchServiceApplication | Get-SPEnterpriseSearchRankingModel
share|improve this answer
    
before I celebrate too quickly, let me confirm that the results I am seeing on my machine are indeed the correct results, but it looks like it's working! Will come back soon to confirm –  Jaap Vossers Sep 21 '10 at 10:02
    
Thank you so much Steve. It works! Can I ask you how you found out about this? –  Jaap Vossers Sep 21 '10 at 10:58
3  
When you query for a project in People search the URL contains k= this indicated to me a KeywordQuery was used and not a FullTextSqlQuery. I tried to run a KeywordQuery from powershell and found it returned no results. I attached the debugger to SharePoint and set a breakpoint at KeywordQuery.Execute() In the debugger I inspected all the properties of KeywordQuery and discovered the mysterious GUID. When I added this to my KeywordQuesry it started to work. –  Steve P Sep 21 '10 at 11:40
    
Cheers, nice one :) –  Jaap Vossers Sep 21 '10 at 21:42

One thing to check is that the name of the field matches. (You probably have but just in case)

I see that you refer to "PastProjects" and "Past projects".

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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