Note: Download Code discussed in this article from Here.
SharePoint 2010 introduced new ways to query Enterprise Search data using KeywordQuery API. For developers, there are two options available for custom Search applications – FullTextSQLQuery (Executes Search SQL Syntax queries) and KeywordQuery (Supports querying both Enterprise Search Index for SharePoint 2010 Standard and Enterprise product and FAST Index for FAST Server for SharePoint 2010 product) APIs.
KeywordQuery API is preferred approach to query data from SharePoint 2010 Enterprise Search engine. Last October I had demonstrated how to use KeyWordQuery API to build Custom Portal Navigation SharePoint 2010 Web Part using Search API. Additionally, Please note that – with both FullTextSQLQuery and FASTQuery are deprecated or obsolate in SharePoint 2013, Microsoft has strengthed their investment in KeywordQuery API in SharePoint 2013.
Pre-requisites
- You must configure Search Service Application on the Farm
- You must run Full Crawl to create crawled properties for any custom SharePoint list or document library metadata
- Create Managed Search Properties for any Custom Managed list or document library metadata and Run Full Crawl again
Solution
In this step by step guide, we will build Portal Navigation Web Part which would render Site Collections Navigation by retrieving Site Collection data from Search Index.
Here are the high levels steps required for developers to build Custom Search Applications using KeywordQuery API.
Step 1 – Create Visual Studio 2010 Solution based on SharePoint 2010 Empty Project Template
Step 2 – Add SharePoint Project Item for Search Application UI & Logic
Depends on what kind of business requirements, plan to add either Custom Web Part (Standard Web Part or Visual Web Part) or Custom Page (Custom Application Page or Site Page).
In our example, we will add Custom Visual Web Part for Portal Navigation Application.
Step 3 – Reference two Search DLLs from the ISAPI directory
Plan to reference Search DLLs from the Visual Studio Project, Search DLLs are available at SharePoint Root in ISAPI folder
- C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.Office.Server.dll
- C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\ISAPI\Microsoft.Office.Server.Search.dll
Step 4 – Import Search Namespaces in the code components
Next step to import all the Namespaces required to instantiate and run KeyWordQuery object.
using Microsoft.Office.Server; using Microsoft.Office.Server.Search; using Microsoft.Office.Server.Search.Query; [KeywordQuery Class defined in this namespace] using Microsoft.Office.Server.Search.Administration;
Step 5 – Instantiate the KeywordQuery object
You have two options, pass either current site collection (Classic MOSS 2007 way), or pass the Search Query and Site Settings Service proxy (New in SP2010) and instantiate KeywordQuery object
Option 1 =>
SearchQueryAndSiteSettingsServiceProxy settingsProxy = SPFarm.Local.ServiceProxies.GetValue <SearchQueryAndSiteSettingsServiceProxy>(); SearchServiceApplicationProxy searchProxy = settingsProxy.ApplicationProxies.GetValue <SearchServiceApplicationProxy>("Search Service Application"); KeywordQuery q = new KeywordQuery(searchProxy);
Option 2 (Preferred Method) =>
SearchServiceApplicationProxy proxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.GetProxy(SPServiceContext.GetContext(SPContext.Current.Site)); KeywordQuery q= new KeywordQuery(proxy);
Step 6 – Set KeywordQuery Object Properties
Next step is to instantiate the KeyWordQuery Object and set the required properties. You can reference available properties on MSDN but here are the major properties you should be aware of.
- QueryText – This is keyword query text (e.g. LastName:”Patel”)
- ResultTypes – Search result types (default is Relevant Results)
- HiddenContraints – Allows you to filter by search scope
- RowLimit – By default, it returns only 50 records, Se this property required to be set to increase number
- RowsPerPage – Paging
- IgnoreAllNoiseQuery
- TrimDuplicates – Trims duplicate results
- EnableNicknames
- EnablePhonetic
- EnableStemming
- EnableSpellCheck
- EnableFQL (Allows you to run FAST Query lanaguage syntax on KeyWordQuery API on FAST Server for SharePoint 2010 server)
In our example, we will set the query to “ContentClass:STS_SITE”, which would return all the Site Collections in the specified scope sorted by Last Modified Date.
KeywordQuery keywordQuery = new KeywordQuery(proxy); keywordQuery.ResultsProvider = SearchProvider.Default; keywordQuery.ResultTypes = ResultType.RelevantResults; keywordQuery.TrimDuplicates = true; keywordQuery.RowLimit = 10; keywordQuery.QueryText = "ContentClass:STS_SITE"; keywordQuery.SortList.Add("LastModifiedTime", Microsoft.Office.Server.Search.Query.SortDirection.Descending); keywordQuery.HiddenConstraints = string.Concat("scope:\"", "All Sites", "\"");
Step 7 – Use SelectProperties string collection to Specify which Properties to Query in ResultSet
Use SelectProperties string collection to return custom managed properties
Out of the box, KeywordQuery API will return only default search properties such as Title, Author etc. To return managed properties, use SelectProperties string collection.
keywordQuery.SelectProperties.Add("Title"); keywordQuery.SelectProperties.Add("Path");
Step 8 – Execute KeywordQuery Object Execute() method and return ResultTableCollection which can be loaded in ADO.NET DataTable Object
ResultTableCollection results = keywordQuery.Execute(); ResultTable result = results[ResultType.RelevantResults]; DataTable dt = new DataTable(); dt.Load(result, LoadOption.OverwriteChanges);
Step 9 – Bind ADO.NET DataTable Object data into ASP.NET or SharePoint Controls for UI
blSites.DataSource = dt; blSites.DataTextField = "Title"; blSites.DataValueField = "Path"; blSites.DataBind();
Final Source Code
You can download Visual Studio 2010 Solution from Sky Drive here. Optionally, you can copy and paste from here.
Markup Code
<asp:BulletedList ID="blSites" runat="server" DisplayMode="HyperLink" />
C# Code
using System; using System.Web.UI; using System.Web.UI.WebControls; using System.Web.UI.WebControls.WebParts; using System.Data; using Microsoft.SharePoint; using Microsoft.Office.Server; using Microsoft.Office.Server.Search; using Microsoft.Office.Server.Search.Query; //KeywordQuery Class defined in this namespace using Microsoft.Office.Server.Search.Administration; namespace SP2010VM.SearchSolutions.CrossSiteCollection_KQL_Farm { public partial class CrossSiteCollection_KQL_FarmUserControl : UserControl { protected void Page_Load(object sender, EventArgs e) { //Instatiate Search Service Application Proxy SearchServiceApplicationProxy proxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy. GetProxy(SPServiceContext.GetContext(SPContext.Current.Site)); //Instatiate KeywordQuery object and set the query KeywordQuery keywordQuery = new KeywordQuery(proxy); keywordQuery.ResultsProvider = SearchProvider.Default; keywordQuery.ResultTypes = ResultType.RelevantResults; keywordQuery.TrimDuplicates = true; keywordQuery.RowLimit = 10; keywordQuery.QueryText = "ContentClass:STS_SITE"; keywordQuery.SortList.Add("LastModifiedTime", Microsoft.Office.Server.Search.Query.SortDirection.Descending); keywordQuery.HiddenConstraints = string.Concat("scope:\"", "All Sites", "\""); //Specify which keyword query properties needs to be returned keywordQuery.SelectProperties.Add("Title"); keywordQuery.SelectProperties.Add("Path"); //Execute the KeywordQuery query and load the results in the table ResultTableCollection results = keywordQuery.Execute(); ResultTable result = results[ResultType.RelevantResults]; DataTable dt = new DataTable(); dt.Load(result, LoadOption.OverwriteChanges); //Bind the table to the bulleted list blSites.DataSource = dt; blSites.DataTextField = "Title"; blSites.DataValueField = "Path"; blSites.DataBind(); } } }
References
- Keyword Query Syntax Reference – http://msdn.microsoft.com/en-us/library/office/ee558911(v=office.14)
- Sorting search results in SharePoint 2013 (Still applicable to 2010) – http://msdn.microsoft.com/library/office/jj938031(v=office.15)
- How to: Use the MOSS Enterprise Search KeywordQuery class – http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2008/02/19/how-to-use-the-moss-enterprise-search-keywordquery-class.aspx
- How to: Use the SharePoint 2010 Enterprise Search KeywordQuery Class -http://www.dotnetmafia.com/blogs/dotnettipoftheday/archive/2010/08/12/how-to-use-the-sharepoint-2010-enterprise-search-keywordquery-class.aspx
Exactly what I was looking for ! The ForEach Site approach is way too slow ! Thank you