protected void Page_Load(object sender, EventArgs e) { this.BiblioSearchControl1.Location = this.TitleBarControl1.SelectedLibraryCode; if (WebUtil.PrepareEnvironment(this, ref app, ref sessioninfo) == false) { return; } string strSideBarFile = Server.MapPath("./search_sidebar.xml"); if (File.Exists(strSideBarFile) == true) { this.SideBarControl1.CfgFile = strSideBarFile; } else { this.SideBarControl1.Visible = false; } SetSideBarVisible(); /* * // 是否登录? * if (sessioninfo.UserID == "") * { * sessioninfo.LoginCallStack.Push(Request.RawUrl); * Response.Redirect("login.aspx", true); * return; * } * */ if (this.BrowseSearchResultControl1.ResultCount > 0) { this.BrowseSearchResultControl1.Visible = true; #if FILTER VisibleFilter(true); #endif } // 是否登录? if (sessioninfo.UserID == "") { if (this.Page.Request["forcelogin"] == "on") { sessioninfo.LoginCallStack.Push(Request.RawUrl); Response.Redirect("login.aspx", true); return; } if (this.Page.Request["forcelogin"] == "userid") { sessioninfo.LoginCallStack.Push(Request.RawUrl); Response.Redirect("login.aspx?loginstyle=librarian", true); return; } sessioninfo.UserID = "public"; sessioninfo.IsReader = false; /* * sessioninfo.LoginCallStack.Push(Request.RawUrl); * Response.Redirect("login.aspx", true); * return; * */ } string strError = ""; int nRet = 0; #if NO string strAction = this.Request["action"]; if (strAction == "getdblist") { DoGetDbNameList(); return; } #endif // 如果有参数 string strWord = this.Request["word"]; if (String.IsNullOrEmpty(strWord) == false && this.IsPostBack == false) { string strXml = ""; // string strWord = ""; string strDbName = ""; string strFrom = ""; string strMatchStyle = ""; GetSearchParams(out strWord, out strDbName, out strFrom, out strMatchStyle); // 根据检索参数创建XML检索式 nRet = OpacApplication.BuildQueryXml( this.app, strDbName, // this.Request["dbname"], strWord, strFrom, // this.Request["from"], strMatchStyle, // this.Request["matchstyle"], null, null, app.SearchMaxResultCount, this.BiblioSearchControl1.SearchStyle, // strSearchStyle out strXml, out strError); if (nRet == -1) { goto ERROR1; } string strResultSetNamePrefix = ""; strResultSetNamePrefix = this.Request["resultsetname"]; if (String.IsNullOrEmpty(strResultSetNamePrefix) == true) { strResultSetNamePrefix = Session.SessionID + "_opac_1"; } else { strResultSetNamePrefix = Session.SessionID + "_" + strResultSetNamePrefix; } string strResultSetName = GetResultSetName(strResultSetNamePrefix); LibraryChannel channel = sessioninfo.GetChannel(true); //sessioninfo.Channel. channel.Idle += new IdleEventHandler(channel_Idle); try { long lRet = // sessioninfo.Channel. channel.Search( null, strXml, strResultSetName, "", // strOutputStyle out strError); if (lRet == -1) { goto ERROR1; } #if FILTER app.SetFilterTask(strResultSetName, null); #endif if (app.SearchLog != null) { SearchLogItem log = new SearchLogItem(); log.IP = this.Request.UserHostAddress.ToString(); log.Query = SearchLog.BuildLogQueryString( this.Request["dbname"], strWord, this.Request["from"], this.Request["matchstyle"]); log.Time = DateTime.UtcNow; log.HitCount = nRet; log.Format = "searchcount"; app.SearchLog.AddLogItem(log); } // not found if (lRet == 0) { this.BrowseSearchResultControl1.Visible = false; #if FILTER this.filter.Visible = false; #endif strError = "没有找到"; goto ERROR1; } this.BrowseSearchResultControl1.Clear(); this.BrowseSearchResultControl1.Visible = true; #if FILTER VisibleFilter(true); #endif this.BrowseSearchResultControl1.ResultSetName = strResultSetName; this.BrowseSearchResultControl1.ResultCount = (int)lRet; this.BrowseSearchResultControl1.StartIndex = 0; // 2008/12/15 #if FILTER this.filter.ResultSetName = strResultSetName; #endif string strFormat = this.Request["format"]; if (String.IsNullOrEmpty(strFormat) == false) { this.BrowseSearchResultControl1.FormatName = strFormat; } return; } finally { // sessioninfo.Channel. channel.Idle -= new IdleEventHandler(channel_Idle); sessioninfo.ReturnChannel(channel); } } // 观察特定的结果集 if (this.IsPostBack == false) { string strResultSet = this.Request["resultset"]; string strBaseResultSet = this.Request["base"]; string strTitle = this.Request["title"]; if (string.IsNullOrEmpty(strResultSet) == false) { string strResultsetFilename = PathUtil.MergePath(app.TempDir, // sessioninfo.GetTempDir(), // ?? strResultSet); if (File.Exists(strResultsetFilename) == true) { long lHitCount = CacheBuilder.GetCount(app, strResultsetFilename, true); this.BrowseSearchResultControl1.ResultsetFilename = strResultsetFilename; this.BrowseSearchResultControl1.Visible = true; #if FILTER VisibleFilter(true); this.filter.ResultSetName = strBaseResultSet; #endif string strOffset = this.Request["offset"]; this.BrowseSearchResultControl1.ResultsetOffset = strOffset; #if FILTER this.filter.SelectedNodePath = MakeSelectedPath(strResultSet, strOffset); #endif if (string.IsNullOrEmpty(strOffset) == false) { int nStart = 0; int nLength = -1; BrowseSearchResultControl.ParseOffsetString(strOffset, out nStart, out nLength); if (nLength == -1) { nLength = (int)lHitCount - nStart; } this.BrowseSearchResultControl1.ResultCount = nLength; } else { this.BrowseSearchResultControl1.ResultCount = (int)lHitCount; } if (string.IsNullOrEmpty(strTitle) == false) { this.BrowseSearchResultControl1.Title = strTitle; } } else { strError = "结果集文件 '" + strResultSet + "' 不存在"; goto ERROR1; } } else if (string.IsNullOrEmpty(strBaseResultSet) == false) { // 只用了base参数 this.BrowseSearchResultControl1.Clear(); this.BrowseSearchResultControl1.Visible = true; #if FILTER VisibleFilter(true); #endif this.BrowseSearchResultControl1.ResultSetName = strBaseResultSet; this.BrowseSearchResultControl1.ResultCount = (int)MyWebPage.GetServerResultCount(sessioninfo, strBaseResultSet); this.BrowseSearchResultControl1.StartIndex = 0; #if FILTER this.filter.ResultSetName = strBaseResultSet; #endif } } //this.AdvanceSearchControl1.Channels = sessioninfo.Channels; //this.AdvanceSearchControl1.ServerUrl = app.WsUrl; // this.HeadBarControl1.CurrentColumn = HeaderColumn.Search; return; ERROR1: Response.Write(HttpUtility.HtmlEncode(strError)); Response.End(); }
// 根据记录数量的多少,少的时候可以立即返回结果,多的时候用线程后台处理,然后可以随时查询状态 // 线程用线程池,避免过多耗用线程数目 // 根据结果集名,提取全部书目 XML 记录,然后批处理经过 MarcFilter 过滤,创建若干个子结果集 // 最基本的功能是返回子结果集的显示名,文件名,包含记录数量,供前端显示在界面上 // 较为深入的功能是,将子结果集按照 key 排序归并,而显示出二级条目和数量。二级结果集是子结果集的子结果集 // TODO: 如何及时清理Task对象,避免内存过度膨胀? 是否仅保存最新10个Task对象? void GetFilterInfo( string strResultsetName, string strSelected, string strLang) { string strError = ""; GetFilterInfo result_info = new GetFilterInfo(); if (string.IsNullOrEmpty(strResultsetName) == true) { strError = "结果集名不应为空"; goto ERROR1; } FilterTask t = app.FindFilterTask(strResultsetName); // Task对象是利用 Session 内结果集名来进行管理的 if (t == null) { // 如果一个结果集还没有被后台任务处理,就立即启动一个后台任务 t = new FilterTask(); app.SetFilterTask(strResultsetName, t); string strGlobalResultSetName = ""; bool bShare = false; if (strResultsetName[0] == '#') { strGlobalResultSetName = strResultsetName.Substring(1); } else { // 构造全局结果集名 strGlobalResultSetName = sessioninfo.GetHashCode() + "_" + strResultsetName; LibraryChannel channel = sessioninfo.GetChannel(true); try { // 先把结果集共享 // 管理结果集 // parameters: // strAction share/remove 分别表示共享为全局结果集对象/删除全局结果集对象 long lRet = // sessioninfo.Channel. channel.ManageSearchResult( null, "share", strResultsetName, strGlobalResultSetName, out strError); if (lRet == -1) { goto ERROR1; } bShare = true; } finally { sessioninfo.ReturnChannel(channel); } } FilterTaskInput i = new FilterTaskInput(); i.App = app; i.FilterFileName = Path.Combine(app.DataDir, "cfgs/facet.fltx"); i.ResultSetName = strGlobalResultSetName; i.ShareResultSet = bShare; // i.SessionInfo = sessioninfo; i.TempDir = app.TempDir; i.TaskName = strResultsetName; // Task对象是利用Session内结果集名来进行管理的 i.MaxCount = 1000; // i.aggregation_names = new List<string>() {"author"}; XmlDocument def_dom = GetFacetDefDom(out strError); if (def_dom == null) { goto ERROR1; } i.DefDom = def_dom; ThreadPool.QueueUserWorkItem(t.ThreadPoolCallBack, i); strError = "#pending"; // 表示正在处理,希望前端稍后重新访问 goto ERROR1; } else { if (t.TaskState == TaskState.Processing) { if (t.ProgressRange != 0) { result_info.ProgressValue = (int)(((double)t.ProgressValue / (double)t.ProgressRange) * 100); } strError = "#pending"; // 表示正在处理,希望前端稍后重新访问 goto ERROR1; } if (string.IsNullOrEmpty(t.ErrorInfo) == false) { strError = t.ErrorInfo; goto ERROR1; } GC.Collect(); // 试着释放 Hashtable 等 long lHitCount = MyWebPage.GetServerResultCount(sessioninfo, strResultsetName); XmlDocument def_dom = GetFacetDefDom(out strError); if (def_dom == null) { goto ERROR1; } this.m_facetDom = def_dom; this.m_strLang = strLang; try { // 创建FilterInfo数组 result_info.Items = ResultsetFilter.BuildFilterInfos( strResultsetName, lHitCount, strSelected, GetKeyNameCaption, t.ResultItems, app.TempDir, // sessioninfo.GetTempDir(), 10); // GC.Collect(); // 担心 DpResultSet 未能回收 } catch (Exception ex) { strError = ExceptionUtil.GetAutoText(ex); goto ERROR1; } if (t.HitCount > 1000) { result_info.Comment = "分面导航只提取了当前结果集的前 1000 条记录"; } } // 返回一级节点的名字和包含记录数量 this.Response.Write(MyWebPage.GetResultString(result_info)); this.Response.End(); return; ERROR1: result_info.ErrorString = strError; this.Response.Write(MyWebPage.GetResultString(result_info)); this.Response.End(); }