Search

輕鬆利用KeyWordQuery定製MOSS搜索

    在Windows SharePoint Services 搜索中提供一個新的查詢對象模型,可以在自定義搜索 Web 部件和搜索應用程序中使用此模型來執行對搜索 服務的查詢。此查詢對象模型是在 Microsoft.SharePoint.Search.dll 中找到的 Microsoft.SharePoint.Search.Query 命名空間中實現的。該命名空間包含三個類:Query ,FullTextSqlQuery KeyWordQuery 類。若要確定用於自定義搜索應用程序(FullTextSqlQuery KeyWordQuery)的適當的類,請考慮希望應用程序代碼支持的搜索查詢中的複雜級別。如果只需使用關鍵字語法就可創建所需的應用程序,則您可能更願意使用 KeyWordQuery類。如果爲搜索查詢使用關鍵字語法,則可以將搜索條件直接傳遞給搜索組件而無需通過搜索條件來分析以生成查詢。因此,使用關鍵字語法來構建查詢的過程是很簡單的。 但是,如果要構建更復雜的查詢則關鍵字語法可能不起作用。對於這些查詢,應使用 FullTextSqlQuery 類。例如,關鍵字語法僅支持短語、單詞或前綴的完全匹配項。同樣,儘管可以使用關鍵字語法來指定是包含還是排除特定的搜索條件,但不能構造已包含的和已排除的條件的複雜組。通過使用 FullTextSqlQuery 可以達到此目的。

到此,大家應該對這三個類更進一步瞭解了吧!但Query不適合於直接從代碼中使用,但適合於作爲搜索 查詢對象模型類的基實現。在代碼中,請使用 FullTextSqlQuery KeywordQuery 類。

今天筆者給大家演示的Demo是以KeyWordQuery來定製一個輕量級的搜索級別。希望對大家更進一步學習搜索的定製提供一些小幫助。

前提準備:

1.瞭解KeyWordQuery的成員和相關的屬性和方法。

2.熟練應用QuikPart包裝用戶控件開發webpart

3進入管理中心,SSP先進行搜索設置(進行爬網,下面步驟會具體介紹)

 

Setp1.

建立一個WEBApplication當然你也可以創建自定義web控件,可以參考SDK 添加一個用戶控件,刪除原有的default頁面,在頁面上放置一個TextBox,Lable.GridView.Button!記得添加sharepoint.dll組建。Sharepoint.server.search.dll組建,最後在項目屬性生成後事件寫入:

copy  "$(TargetPath)"C:"Inetpub"wwwroot"wss"VirtualDirectories"80"bin

copy "$(ProjectDir)*.ascx" C:"Inetpub"wwwroot"wss"VirtualDirectories"80"wpresources

以便項目生成,將應用程序集和.ASCX頁面直接打包到指定的目錄下!

 Setp2

以下是本次Demo的源碼:

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Search.ascx.cs" Inherits="SearchControl.Search" %>

            <asp:TextBox ID="txtQueryText" runat="server" Width="194px"></asp:TextBox>

            <asp:Button ID="cmdSearch" runat="server" OnClick="cmdSearch_Click" Text="搜索" Width="56px" /><br />

<table style="width: 503px; height: 207px">

    <tr>

        <td colspan="2" rowspan="3" style="width: 415px">

            <asp:GridView ID="grdResults" runat="server" CellPadding="4" ForeColor="#333333" GridLines="None" Width="520px" AutoGenerateColumns="False" OnPageIndexChanging="grdResults_PageIndexChanging" PageSize="5">

                <FooterStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" />

                <RowStyle BackColor="#EFF3FB" Height="16px" HorizontalAlign="Center" VerticalAlign="Middle" />

                <EditRowStyle BackColor="#2461BF" />

                <SelectedRowStyle BackColor="#D1DDF1" Font-Bold="True" ForeColor="#333333" />

                <PagerStyle BackColor="#2461BF" ForeColor="White" HorizontalAlign="Center" />

                <HeaderStyle BackColor="#507CD1" Font-Bold="True" ForeColor="White" Height="20px" HorizontalAlign="Center" VerticalAlign="Middle" />

                <AlternatingRowStyle BackColor="White" />

                <Columns>

                    <asp:HyperLinkField DataNavigateUrlFields="Path" DataTextField="Title" HeaderText="標題">

                        <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" />

                    </asp:HyperLinkField>

                    <asp:BoundField DataField="Author" HeaderText="創建者">

                        <HeaderStyle HorizontalAlign="Center" VerticalAlign="Middle" />

                    </asp:BoundField>

                </Columns>

            </asp:GridView>

        </td>

    </tr>

    <tr>

    </tr>

    <tr>

    </tr>

    <tr>

        <td colspan="2" style="width: 415px">

            <asp:Label ID="lblQueryResult" runat="server" Text=""></asp:Label></td>

    </tr>

</table>

 

.CS文件:記得引用using Microsoft.Office.Server.Search.Query; using Microsoft.SharePoint;,具體代碼一些意思,筆者在下面做了相應的註釋:

 

 

using System;

using System.Data;

using System.Configuration;

using System.Collections;

using System.Web;

using System.Web.Security;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Web.UI.WebControls.WebParts;

using System.Web.UI.HtmlControls;

using Microsoft.SharePoint;

using Microsoft.Office.Server.Search.Query;

 

 

 

namespace SearchControl

{

    public partial class Search : System.Web.UI.UserControl

    {

        protected void Page_Load(object sender, EventArgs e)

        {

 

        }

 

        protected void cmdSearch_Click(object sender, EventArgs e)

        {

            if (txtQueryText.Text != string.Empty)

            {   //當搜索框不爲空時,執行查詢

                keywordQueryExecute(txtQueryText.Text);

            }

            else

            {

                lblQueryResult.Text = "You must enter a search word.";

            }

        }

 

        private void keywordQueryExecute(string strQueryText)

        {

            SPSite site = new SPSite("http://mosingserver/");//實例化一個site對象

            KeywordQuery kRequest = new KeywordQuery(site);

            string strQuery =strQueryText;//關鍵字查詢的文本

            kRequest.QueryText = strQuery;

            //在MOSS中搜索結果默認返回的屬性值有默認返回以下屬性字段:Work ID ,Rank ,Title ,Author ,Size ,Path ,Description

   //Write ,SiteName ,CollapsingStatus ,HitHighlightedSummary ,HitHighlightedProperties ,ContentClass, IsDocument,PictureThumbnailURL

           //用selectproperties屬性查找指定的字段

            kRequest.SelectProperties.Add("Title");

            kRequest.SelectProperties.Add("Author");

            kRequest.SelectProperties.Add("Path");

            kRequest.ResultTypes = ResultType.RelevantResults;//返回RelevantResults類型,總共有五種類型

            ResultTableCollection resultTbls = kRequest.Execute();//自行關鍵字查詢

            if (resultTbls.Count > 0)//當查詢結果不爲空時

            {

                site.AllowUnsafeUpdates = true;

                ResultTable tblResult = resultTbls[ResultType.RelevantResults];//記得在這邊需在指定下返回類型

                if (tblResult.TotalRows == 0)

                {

                    grdResults.Visible = false;

                    lblQueryResult.Text = "No Search Results Returned.";

                }

                else

                {

                    lblQueryResult.Text = "";

                    grdResults.Visible =true;

                    ReadResultTable(tblResult);

                }

 

            }

        }

 

        void ReadResultTable(ResultTable rt)

        {

            DataTable relResultsTbl = new DataTable();//定義一個DataTable

            relResultsTbl.TableName = "Relevant Results";

            DataSet ds = new DataSet("resultsset");//定義一個DataSet把數據加載到表中

            ds.Tables.Add(relResultsTbl);

            ds.Load(rt, LoadOption.OverwriteChanges, relResultsTbl);//提供一個或多個結果集

            fillResultsGrid(ds);

        }

 

        void fillResultsGrid(DataSet ds)

        {

            grdResults.AllowPaging = true;

            grdResults.PageSize = 8;

            grdResults.DataSource = ds;//綁定GridView

            grdResults.DataBind();

        }

 

        protected void grdResults_PageIndexChanging(object sender, GridViewPageEventArgs e)

        {

            grdResults.PageIndex= e.NewPageIndex;

            grdResults.DataBind();

 

        }

   }

}

 Setp3

直接生成項目。

在這筆者提醒下大家:在進行搜索操作時,需提前對搜索的站點進行爬網,否則搜不到內容!

首先進入管理中心->ssp->搜索設置    進行完全爬網

在這筆者提醒下:在爬網的時候,CPU佔用率會非常的大,稍等片刻,刷新頁面,就可看到爬網的狀態已變成空閒咯!

然後進入頁面輸入搜索內容,請看:

也許有人會有疑問,搜索的內容應該加以權限控制,沒錯!不夠此Demo筆者就沒給它加上列表條目權限,因此一個普通用戶搜索一些內容,他可能就會把該站點和這些相關的內容都搜索出來。這對企業應用來說是絕對不行的!

解決辦法:

1.    管理員可以對列表條目進行精確的權限管控,比如說允許那些用戶或用戶組可以查看到搜索到該列表條目。具體操作是斷開指定列表當前的繼承權限,然後刪除它原本的所有權限,在重新分配權限給他,一般我們把新權限設爲NONE就可以了(具體代碼操作可以參考前面“提升用戶權限”),這樣沒授權的用戶就看不到該條目也就搜索不到咯!不夠筆者昨天試了下,把對該條目的用戶權限類型SPRoleType設爲NONE或guest,項目運行報錯:“值不在範圍內”(希望哪位朋友如果清楚的話,及時的指點下出錯的原因)

2.    在開發定製的時候,可根據列表欄位進行用戶匹配,不相干的人就搜索不到(這塊不太熟,網上應該有資料)

 

 

以下是SDK上的源碼(筆者直接COPY出來,便於大家參考!)

SDK上是直接創建一個web自定義控件!生成的應用程序集部署到指定應用程序_app_bin目錄下!最後生成.dwp文件然後直接在web部件上載,直接添加到頁面就可以用!

using System;

using System.Collections.Generic;

using System.ComponentModel;

using System.Text;

using System.Web;

using System.Web.UI;

using System.Web.UI.WebControls;

using System.Drawing;

using System.Xml;

using System.Xml.Serialization;

using System.Data;

using Microsoft.SharePoint.WebPartPages;

using Microsoft.Office.Server;

using Microsoft.Office.Server.Search.Query;

 

 

namespace CustomSearchWebPart

{

   

    [ToolboxData("<{0}:clsSearchQuery runat=server></{0}:clsSearchQuery>")]

    [XmlRoot(Namespace = "CustomSearchWebPart")]

    public class clsSearchQuery : WebPart

    {

        [Bindable(true)]

        [Category("Appearance")]

        [DefaultValue("")]

        [Localizable(true)]

 

        Button cmdSearch;

        TextBox txtQueryText;

        Label lblQueryResult;

        DataGrid grdResults;

 

        protected override void CreateChildControls()

        {

            Controls.Clear();

            txtQueryText = new TextBox();

            this.Controls.Add(txtQueryText);

            cmdSearch = new Button();

            cmdSearch.Text = "Start Search";

            cmdSearch.Click += new EventHandler(cmdSearch_Click);

            this.Controls.Add(cmdSearch);

            lblQueryResult = new Label();

            this.Controls.Add(lblQueryResult);

 

        }

 

        void cmdSearch_Click(object sender, EventArgs e)

        {

            if (txtQueryText.Text != string.Empty)

            {

                keywordQueryExecute(txtQueryText.Text);

 

            }

            else

            {

                lblQueryResult.Text = "You must enter a search word.";

            }

            

        }

 

 

        //Execute Keyword Query

     private void keywordQueryExecute(string strQueryText)

        {

            KeywordQuery kRequest = new KeywordQuery(ServerContext.Current);

            string strQuery = "author:" + strQueryText;

            kRequest.QueryText = strQuery;

            //to return relevant results

            kRequest.ResultTypes |= ResultType.RelevantResults;

            ResultTableCollection resultTbls = kRequest.Execute();

            if ((int)ResultType.RelevantResults != 0)

            {

                ResultTable tblResult = resultTbls [ResultType.RelevantResults];

                if (tblResult.TotalRows == 0)

                {

                  lblQueryResult.Text = "No Search Results Returned.";

                }

                else

                {

                    ReadResultTable(tblResult);

                }

 

            }

 }

 

void ReadResultTable(ResultTable rt)

        {

            DataTable relResultsTbl = new DataTable();

            relResultsTbl.TableName = "Relevant Results";

            DataSet ds = new DataSet("resultsset");

            ds.Tables.Add(relResultsTbl);

            ds.Load(rt,LoadOption.OverwriteChanges,relResultsTbl);

            fillResultsGrid(ds);

        }

 

        private void fillResultsGrid(DataSet grdDs)

        {

//Instantiate the DataGrid, and set the DataSource

            grdResults = new DataGrid();

            grdResults.DataSource = grdDs;

 

//Set the display properties for the DataGrid

            grdResults.GridLines = GridLines.None;

            grdResults.CellPadding = 4;

            grdResults.Width = Unit.Percentage(100);

            grdResults.ItemStyle.ForeColor = Color.Black;

            grdResults.ItemStyle.BackColor = Color.AliceBlue;

            grdResults.ItemStyle.Font.Size = FontUnit.Smaller;

            grdResults.ItemStyle.Font.Name = "Tahoma";

            grdResults.HeaderStyle.BackColor = Color.Navy;

            grdResults.HeaderStyle.ForeColor = Color.White;

            grdResults.HeaderStyle.Font.Bold = true;

            grdResults.HeaderStyle.Font.Name = "Tahoma";

            grdResults.HeaderStyle.Font.Size = FontUnit.Medium;

 

/*Turn off AutoGenerate for the columns, so the DataGrid

doesn't automatically bind to all of the columns

in the search results set.

Then create and configure only the columns you want to

 include in the DataGrid.

*/

            grdResults.AutoGenerateColumns = false;

            HyperLinkColumn colTitle = new HyperLinkColumn();

            colTitle.DataTextField = "Title";

            colTitle.HeaderText = "Title";

            colTitle.DataNavigateUrlField = "Path";

            grdResults.Columns.Add(colTitle);

            BoundColumn colAuthor = new BoundColumn();

            colAuthor.DataField = "Author";

            colAuthor.HeaderText = "Author";

            grdResults.Columns.Add(colAuthor);

 

//Bind the data to the DataGrid

            grdResults.DataBind();

//Add the DataGrid to the controls

            Controls.Add(grdResults);

        }

    }

}

生成項目之後,把程序集放入_app _bin目錄下,然後在web.config,<SafeControls></ SafeControls >寫入

<SafeControl Assembly="CustomSearchWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"

 Namespace="CustomSearchWebPart" TypeName="*" Safe="True" />

聲明此應用程序集爲安全!

注意:在webconfig   安全級別記得設爲最高:trust=Full

(筆者建議直接生成強名稱程序集放入GAC中,就可以省以上這一步驟!)

最後Creating a .webpart File

You can manually create and edit a simple .webpart file using a text editor such as Notepad. The following code example shows the XML syntax for a simple Web Part, without a strong name:

 

Xml Copy Code

<?xml version="1.0" encoding="utf-8"?>

<webParts>

 <webPart xmlns="http://schemas.microsoft.com/WebPart/v3">

    <metaData>

     <type name="CustomASPNETWebPart.customSearchQuery, CustomASPNETWebPart, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />

      <importErrorMessage>Cannot import this Web Part.</importErrorMessage>

    </metaData>

    <data>

      <properties>

        <property name="Title" type="string">Custom Search Query</property>

      </properties>

    </data>

 </webPart>

</webParts>

最後去站點web部件庫直接上載剛剛創建的CustomSearchWebPart.wpt文件!打開頁面加載CustomSearchWebPart 部件 。完成!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章