Pergunta

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);
            }
        }
    }
}
Foi útil?

Solução

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

Outras dicas

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".

Licenciado em: CC-BY-SA com atribuição
Não afiliado a sharepoint.stackexchange
scroll top