下面我講寫一下最近研究的自定義搜索
1.我們是針對一個大數據列表進行搜索。
2.自定義的搜索范圍
3.自定義搜索結果頁和簡單分頁
4.搜索結果顯示列表某一字段的值
下面我們按順序來詳細的介紹
創建一個列表 ,列表名稱:NoteList
字段如圖

下面請讀者自行為列表添加一些數據。能填寫規整點的數據最好。有利於我們最后搜索出的結果更清晰,每條數據盡量上傳個word文檔。word文檔中也最好有數據。
這樣才能體現出moss爬網的強大。呵呵

這是我添加的幾條數據

下面我們來定義這個列表的搜索范圍。
打開管理中心》管理服務器應用程序》Search Service Application》查詢和結果》范圍
新建范圍

點擊確定后,會看到剛添加的范圍,然后為這個范圍添加規則

這時候我們點擊確定,就創建了新的搜索規則
下面打開網站,網站設置》網站集管理》搜索范圍
這時候我們會發現一個未使用的規則,點擊 顯示組

編輯顯示組

勾上娛樂新聞點確定
現在我們回到管理中心的 Search Service Application 點擊內容源 開始爬網

泡杯咖啡,等會吧。建議是新網站,這樣爬網的速度要快很多。
提醒:如果你等了很長時間還沒爬完,我建議你刪了這個Service 然后新建一個Search Service Application然后新建應用程序池,再爬網。
爬網完成后。如圖:

大家來分析下這個圖。
作者:系統賬戶 其實就是這條數據的創建者。
標題:就是列表項的標題
標題下的文字是摘要,也就是這條列表項中附件里的內容
還有創建日期和item地址。
現在我們用的是moss自己的搜索結果頁。下面我們來進行自己開發。
首先搜索會用到兩個類庫,KeywordQuery和FullTextSqlQuery.
KeywordQuery是針對輕量級搜索和簡單搜索,如果我們想要拼湊更多的搜索條件,我們就要使用到FullTextSqlQuery.下面的例子就是FullTextSqlQuery來做的。
通過上圖我們可以看到這些數據,如果我們想讓新聞中的其他字段也顯示在搜索結果頁中應該如何去做呢?
再次回到我們的管理中心的Serach Service Application中,找到左側導航中的 元數據屬性
點新建托管屬性

點添加映射

搜索NoteList這個里面的字段名稱,就可以找到這個字段。點確定
保存后 在以爬網屬性里面就可以搜索到

以映射到 NoteCompanyName
按照上述步驟,我們依次把Notelist列表中的其他字段添加進來。
NoteType 映射名 NoteTypeName
NoteAuthor 映射名 NoteAuthorName
然后我們在內容源中再進行一次完全爬網。
下面我們就開始寫我們的代碼了。
用vs2010新建一個空白的SharePoint項目
然后添加一個名稱為FullTextSqlQueryWebpart的webpart
在添加一個名稱為FullTextSqlQueryControl的用戶控件
FullTextSqlQueryWebpart中的代碼為:
private string fullTextSql = string.Empty;
[Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("查詢語句"), WebDescription("請輸入查詢語句")]
public string FullTextSql
{
get { return fullTextSql; }
set { fullTextSql = value; }
}
private int pageSize = 10;
[Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("每頁顯示條數"), WebDescription("請輸入每頁顯示條數")]
public int PageSize
{
get { return pageSize; }
set { pageSize = value; }
}
private const string _ascxPath = @"~/_CONTROLTEMPLATES/FullTextSqlQuerySearch/FullTextSqlQueryControl.ascx";
protected override void CreateChildControls()
{
try
{
FullTextSqlQueryControl control = (FullTextSqlQueryControl)Page.LoadControl(_ascxPath);
control.FullTextSql = this.FullTextSql;
control.PageSize = this.PageSize;
this.Controls.Add(control);
}
catch (Exception ex)
{
Label label = new Label();
label.Text = "您好,該功能不能正常顯示,請聯系管理員或檢查雜項是否填寫正確";
Controls.Add(label);
}
}
FullTextSqlQueryControl.ascx中的代碼是
<script type="text/javascript" src="/_layouts/Knowledge/js/jquery-1.6.1.min.js"></script>
<style type="text/css">
.searchtable
{
width: 100%;
}
.tdAbstract
{
color: #548A9E;
}
.tdAbstract span
{
color: Red;
font-weight:bold;
}
.trAbstract
{
background-color: #F4F4F4;
height:30px;
}
.trAbstract span
{
font-weight: bold;
}
</style>
<script type="text/javascript">
function search(startpagenum) {
var keyword = $("#txtQueryText").val();
var href = window.location + "";
var pageurl = href.split("?")[0];
window.location = pageurl + "?keyword=" + keyword + "&startnum=" + startpagenum;
}
$(document).ready(function () {
$("#searchTable td[class='tdAbstract']").each(function () {
var html = $(this).html();
});
});
</script>
<table class="searchtable" cellpadding="0" cellspacing="0" id="searchTable">
<tr>
<td>
<input type="text" id="txtQueryText" name="txtQueryText" value="<%=base.KeyWord %>"
style="border: 1px solid black; height: 20px; width: 250px;" />
<input type="button" value="搜索" onclick="search('1')" />
</td>
</tr>
<asp:Repeater runat="server" ID="repSearchSource">
<ItemTemplate>
<tr>
<td>
<table class="searchtable" cellpadding="0" cellspacing="0">
<tr>
<td style="font-weight: bold; vertical-align: middle; height:30px;">
<img src="<%# GetImageUrl(Eval("ContentClass").ToString()) %>" /><%#Eval("Title") %>
</td>
<td style="color: #ADC1CC;">
<%#Eval("NoteCompanyName")%>
</td>
<td style="color: #ADC1CC;">
<%#Eval("NoteAuthorName")%>
</td>
</tr>
<tr>
<td colspan="3" class="tdAbstract">
<%# GetKeyWordColor(Eval("HitHighlightedSummary").ToString())%>
</td>
</tr>
<tr class="trAbstract">
<td colspan="2">
<span>新聞分類:</span><%#Eval("NoteTypeName") %></td>
<td>
<span>更改日期:</span><%#Eval("Write")%></td>
</tr>
</table>
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
<tr>
<td style="text-align: center;">
<asp:Label ID="lblQueryResult" runat="server" Text=""></asp:Label>
</td>
</tr>
</table>
這里我利用jquery改變了一下關鍵字的顏色。
FullTextSqlQueryControl.ascx.cs中的代碼是
public string FullTextSql { get; set; }
public int PageSize { get; set; }
private int pageStartNum = 1;
public int PageStartNum
{
get
{
if (!string.IsNullOrEmpty(this.Request.QueryString["startnum"]))
{
int.TryParse(this.Request.QueryString["startnum"], out this.pageStartNum);
}
return this.pageStartNum;
}
}
private string keyWord = string.Empty;
public string KeyWord
{
get
{
if (!string.IsNullOrEmpty(this.Request.QueryString["keyword"]))
{
this.keyWord = this.Request.QueryString["keyword"];
}
return this.keyWord;
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (KeyWord != string.Empty)
{
//當搜索框不為空時,執行查詢
string query = string.Format(FullTextSql, KeyWord);
try
{
CustomSearch(query);
}
catch (Exception ex)
{
}
}
else
{
lblQueryResult.Text = "You must enter a search word.";
}
}
private DataTable CustomSearch(string query)
{
DataTable result = new DataTable();
string url = SPContext.Current.Web.Url;
using (SPSite site = new SPSite(url))
{
int endnum = PageStartNum + PageSize;
ResultTableCollection rt = null;
using (FullTextSqlQuery fullQuery = new FullTextSqlQuery(site))
{
ScopeInformation[] ss = fullQuery.GetScopes();
//獲取或設置查詢的語言環境
fullQuery.Culture = System.Globalization.CultureInfo.InvariantCulture;
//查詢語句
fullQuery.QueryText = query;
//獲取或設置一個值,指定搜索結果類型
fullQuery.ResultTypes = ResultType.RelevantResults;
fullQuery.EnableStemming = false;
//獲取或設置一個布爾值,指定是否應執行搜索查詢,如果查詢文本只包含干擾詞
fullQuery.IgnoreAllNoiseQuery = true;
//是否刪除重復項
fullQuery.TrimDuplicates = true;
//獲取或設置一個值,指定是否查詢返回的結果包含全部或任何指定的搜索條件
fullQuery.KeywordInclusion = KeywordInclusion.AnyKeyword;
fullQuery.StartRow = this.PageStartNum;
fullQuery.RowLimit = endnum;
if (SPSecurity.AuthenticationMode != System.Web.Configuration.AuthenticationMode.Windows)
fullQuery.AuthenticationType = QueryAuthenticationType.PluggableAuthenticatedQuery;
else
fullQuery.AuthenticationType = QueryAuthenticationType.NtAuthenticatedQuery;
rt = fullQuery.Execute();
}
ResultTable resultTable = rt[ResultType.RelevantResults];
result.Load(resultTable, LoadOption.OverwriteChanges);
//分頁
string strPage = GetPageStrByCount(resultTable.TotalRows);
this.lblQueryResult.Text = strPage;
this.repSearchSource.DataSource = result;
this.repSearchSource.DataBind();
}
return result;
}
private string GetPageStrByCount(int count)
{
StringBuilder sb = new StringBuilder();
if (count > this.PageSize)
{
int pageSumNum = count / this.PageSize;
for (int i = 0; i < pageSumNum + 1; i++)
{
sb.Append(string.Format("<span style='width:20px;color:Blue;cursor:pointer;' onclick=\"search('{1}')\">[{0}]</span>", i + 1, i * PageSize + 1));
}
lblQueryResult.Text = "";
}
return sb.ToString();
}
/// <summary>
/// 根據不同的數據類型 顯示不同的圖片,目前只顯示了兩種
/// </summary>
/// <param name="contentclass">數據類型</param>
/// <returns></returns>
public string GetImageUrl(string contentclass)
{
string url = string.Empty;
if (contentclass == "STS_ListItem_GenericList")
url = "/_layouts/images/STS_ListItem16.gif";
if (contentclass == "STS_List_GenericList")
url = "/_layouts/images/STS_List_GenericList16.gif";
return url;
}
public string GetKeyWordColor(string summary)
{
string result = string.Empty;
if (!string.IsNullOrEmpty(summary))
{
result = summary.Replace("<c0>", "<span>");
result = result.Replace("</c0>", "</span>");
}
return result;
}
然后部署webpart
在頁面上添加webpart,編輯修改雜項。
query語句是:
SELECT ContentClass,WorkId,Rank,Title,Author,Size,Path,Write,Filename,SiteName,PictureThumbnailURL,SiteTitle,CollapsingStatus,HitHighlightedSummary,
HitHighlightedProperties,PictureURL,IsDocument,WorkEmail,CreatedBy,FileExtension,NoteCompanyName,NoteTypeName,NoteAuthorName from scope()
where "scope" = '娛樂新聞' AND FREETEXT(defaultproperties, '{0}')
這個里面的{0}是關鍵字的位置,在代碼中我會通過占位符的形式把關鍵字傳入。
具體語句的意思祥看官網SDK。
我們搜索Crazy,也就是列表里面NoteAuthor的作者那列的值

寫到這里總算寫完了。如有不明白的地方,請留言。也沒怎么寫過博文,表達能力有限,大家見諒。moss技術交流群:69022156
