SharePoint2010 自定义搜索
下面我讲写一下最近研究的自定义搜索
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