Using KeywordQuery Class in SharePoint Query Object Model

In order to develop custom search web parts or applications that support ‘search-by-keyword’ scenario, SharePoint Query object model exposes KeywordQuery Class.

Using KeywordQuery Class, We can construct keyword search queries for :

  • SharePoint Foundation Search
  • SharePoint Server Enterprise Search
  • FAST Search Server 2010

This class exposes QueryText property which accepts query(keywords)  in Keyword query syntax or KQL (Keyword Query Language). Using KQL, search terms are passed directly to the Search Service.

KQL allows keywords, phrases, and Managed Property names to create sophisticated search queries.In addition, KQL supports Boolean operators and wild cards.

Some Keyword Query Examples 

  1. Moss AND Sharepoint: Returns items containing both “Moss” and “Sharepoint”
  2. Lastname:K* :  Returns people whose last name starts with K
  3. AverageRating>1  : Returns items whose average rating is greater than one
  4. Finance +isDocument:1  : Returns documents that are related to Finance
  5. Finance +Author:”Amit Kumawat” : Returns items authored by Amit Kumawat
  6. Finance Scope:”Local SharePoint Sites” Scope:”Internet Sites” NOT Scope:”Shared Folder”
Using Scopes in KeywordQuery
The example 6. above is worth to take a look. It shows how we can include scopes in keywordquery.
So, it will search for keyword “Finance”  in scopes ”Local SharePoint Sites” and ”Internet Sites”  but not ”Shared Folder“.

 

In SharePoint Server 2010, KQL  also supports :

  • Prefix matching for free-text and property restriction queries
  • Property operators with non-text fields

For more details on forming queries based on KQL, Please refer Keyword Query Syntax Reference

In below example, We create a custom web part that uses KeywordQuery Class to  perform search. Create a new SharePoint project in Visual Studio 2010 and add reference to below dlls (from Program FilesCommon FilesMicrosoft SharedWeb Server Extensions14ISAPI):

  • Microsoft.Office.Server.dll
  • Microsoft.Office.Server.Search.dll.

[Note: If you are working with SharePoint Foundation, you need to use another namespace, Microsoft.SharePoint.Search.Query, that contains a subset of the SharePoint Server functionality. It comprises the query object model with reduced functionality and is found in Microsoft.SharePoint.Search.dll.]

In the project, add a new web part and use below code sample :
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 System.Data;
using Microsoft.Office.Server.Search.Query;
using Microsoft.Office.Server.Search.Administration;

namespace AmitKumawat.SP2010.Samples.CustomSearchWebPart
{
    [ToolboxItemAttribute(false)]
    public class CustomSearchWebPart : WebPart
    {
       protected Button btnSearch;
       protected TextBox txtSearchBox;
       protected Label lblResults;
       protected GridView gridSearchResults;

        protected override void CreateChildControls()
        {

            txtSearchBox = new TextBox();
            this.Controls.Add(txtSearchBox);

            lblResults = new Label();
            this.Controls.Add(lblResults);

            btnSearch = new Button();
            btnSearch.Text = "Find";
            btnSearch.Click += new EventHandler(btnSearch_Click);
            this.Controls.Add(btnSearch);

        }

        void btnSearch_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(txtSearchBox.Text))
            {
                lblResults.Text = "Please enter words to search for";
                return;
            }

            ExecuteKeywordQuery(txtSearchBox.Text);

        }

        void ExecuteKeywordQuery(string keywordQueryText)
        {
          //Get a proxy for Search Service Application(SSA). The SSA serves search queries.
             SearchServiceApplicationProxy SSAProxy = (SearchServiceApplicationProxy)SearchServiceApplicationProxy.
                GetProxy(SPServiceContext.GetContext(SPContext.Current.Site));
            KeywordQuery keywordQuery = new KeywordQuery(SSAProxy);
            //keyword search using default provider. We can use "FAST" or "SharepointSearch" to be specific.
            keywordQuery.ResultsProvider = SearchProvider.Default;
            keywordQuery.QueryText = keywordQueryText;
            keywordQuery.ResultTypes |= ResultType.RelevantResults;

            ResultTableCollection searchResults = keywordQuery.Execute();

            if (searchResults.Exists(ResultType.RelevantResults))
            {
                ResultTable searchResult = searchResults[ResultType.RelevantResults];
                DataTable result = new DataTable();
                result.TableName = "SearchResults";
                result.Load(searchResult, LoadOption.OverwriteChanges);
                PopulateResultsGrid(result);
            }
        }

        private void PopulateResultsGrid(DataTable resultsTable)
        {
            gridSearchResults = new GridView();
            gridSearchResults.DataSource = resultsTable;
            gridSearchResults.DataBind();
            Controls.Add(gridSearchResults);
        }

        protected override void Render(HtmlTextWriter writer)
        {
            writer.Write("<table width='100%'><tr><td>");
            txtSearchBox.RenderControl(writer);
            writer.Write("</td><td>");
            btnSearch.RenderControl(writer);
            writer.Write("</td></tr><tr><td colspan='2'>");
            lblResults.RenderControl(writer);
            writer.Write("</td></tr><tr><td colspan='2'>");
            if(gridSearchResults!=null)
            gridSearchResults.RenderControl(writer);
            writer.Write("</td></tr></table>");
        }

    }
}

If you want to use a specific SSA , you can get reference of it by using its name as:

SearchQueryAndSiteSettingsServiceProxy settingsProxy = SPFarm.Local.ServiceProxies.GetValue<SearchQueryAndSiteSettingsServiceProxy>();
 // Get the SSA proxy by name
SearchServiceApplicationProxy SSAProxy = settingsProxy.ApplicationProxies.GetValue<SearchServiceApplicationProxy>("Search Service Application 1");

In your SharePoint farm, You must create and configure a Search service application(SSA) before using Search. You can follow steps here to create SSA.

10 Responses to “Using KeywordQuery Class in SharePoint Query Object Model”
  1. vikram says:

    Hi great article very useful.Can we use custom service application in sharepoint 2010 to publish the content which i get using FQL in Fast search.I ahve a scenario of the same .Can you please suggest some idea.Thanks in advance..

    • Amit Kumawat says:

      You can expose the search via a WCF. You can return new Dataset filled with the Datatable in ExecuteKeywordQuery method above.

      For Fast, you have to use the relevant search provider : keywordQuery.ResultsProvider = SearchProvider.Fast;

  2. waiwlin says:

    Nice! very useful

  3. [...] we are ready to get refiners in code. We can use Keyword query class like I have demonstrated in another post with some changes as below [...]

  4. shaik says:

    Hi great article very useful.i have scenario in which i wnat to dispaly custom page in whcih i want to display cutom results in grid as well as refinement panel.Am using KeywordQuery for custom results.Can you please suggest some idea.Thanks in advance..

  5. Amit says:

    Thanks for sharing this Nice article.

    I need to fetch data for say last five days. I am using querytext property for the same as below:

    DateTime TodayMinusFive = DateTime.Now.AddDays(-5);
    keywordQuery.QueryText = “write > ” + TodayMinusFive.ToString()

    Here write is sharepoint managed property for update date.
    search having querytext =”" returns 30 records but when I apply above filter, it returns zero records but it should return me atleast 10 records. (based on data) can you help me how to compare date using keyword querytext.

  6. Vipul Kelkar says:

    Hi Amit,
    With the keyword query I am able to retrieve the search results. I need to filter the search results on the categories : ‘Only documents’,'Pages and documents’

    I looked through the keyword query reference here “http://msdn.microsoft.com/en-us/library/ee558911.aspx” and by concatenating “filetype:docx” to my query text i could filter the results to word doucments. But Is there any way we can get all the documents with a single filter and not add individual filters for DOCX,XLSX, PPT etc. Also, how could i get other document types like TXT,VISIO files etc !!

    • Amit Kumawat says:

      You are using property restriction in the query to find out what you need and I think its good enough.

  7. Doula says:

    Thanks a lot for the gr8 post…!!!

  8. Sylvain says:

    Doesn’t works with Foundation 2010 !

Leave a Reply

Subscribe

Get every post delivered to your inbox via FeedBurner :

© 2010-2013 Extreme Sharepoint | The content is copyrighted to Amit Kumawat and may not be reproduced on other websites.