NATA1 Walk Through

本文介绍了在网站实现NATA1搜索引擎的过程。包括获取代码、构建项目、创建SQL数据库及存储过程,设置web.config文件,修复爬虫的超时和链接处理问题,添加Nata1.dll到工具箱,构建搜索和结果页面,设置模板和错误处理,最终实现网站页面搜索。

My mission, To implement NATA1 to spider and search my .Text site. Props to Paul [Sedgewick@Nata1.com] for sharing his source and walkthough to get me started on this, and for responding to my pleas for help

OK, so the NATA1 project is not quite as easy to implement as you were lead to believe at (http://www.nata1.com/)  the NATA2 does not appear to be "Open" yet, and the version 1.1 available via the download link at the bottom of the page at (http://www.nata1.com/download/default.aspx) has a couple of bugs, but we can fix this all in a jiffy... 

So start by getting the code, and make sure you can build it in your VS.NET. 

Choose or create your SQL database, and run the Nata1SqlScripts/tables.SQL to make the required tables... They all will co-exist nicely in your current sites database... Then run the Nata1SqlScripts/Sprocs.SQL to make the stored procedures...  If your database login is not an admin (sa) or a dbo, then you should remember to give your user execute permissions to the new stored procedures at this point.

Next on to the web.config...

In the web application where you hope to use NATA1, you are going to need to add a bunch of settings

for .Text you already have a configSections.. so add the following keys

<configuration>

<configSections>

<sectionGroup name="Nata1">

<section name="binPath" type="Nata1.Nata1SectionHandler,Nata1" />

<section name="sites" type="Nata1.Nata1SectionHandler,Nata1" />

<section name="log" type="Nata1.Nata1SectionHandler, Nata1" />

<section name="database" type="Nata1.Nata1SectionHandler, Nata1" />

<section name="preferedIndexTime" type="Nata1.Nata1SectionHandler, Nata1" />

<section name="indexRequestTimeOut" type="Nata1.Nata1SectionHandler, Nata1" />

<section name="indexing" type="Nata1.Nata1SectionHandler, Nata1" />

<section name="indexService" type="Nata1.Nata1SectionHandler, Nata1" />

<section name="google" type="Nata1.Nata1SectionHandler, Nata1" />

</sectionGroup>

<section name="exceptionManagement" type="Microsoft.ApplicationBlocks.ExceptionManagement.ExceptionManagerSectionHandler, Microsoft.ApplicationBlocks.ExceptionManagement" />

</configSections>

Then after the close of your systemWeb section () but before the close of your configuration section () you should add the following... editing the file path (My implementation does not use this), site URL, SQL connection string, and the Google Key (if applicable).  I have removed the quotes from the sections you need to edit, so if you forget one your application will tell you your .config is invalid...  you need to replace all of my square brackets with quoted strings.

<Nata1>

<binPath>

<add key="filePath" value=[FILE PATH HERE eg C:/siteName/searchEngine/] />

</binPath>

<sites>

<add key="site" value=[BASE URL HERE eg http://blog.yoursite.com]/>

<add key="defaultPage" value="index.aspx" />

</sites>

<log>

<add key="filePath" value="c:/eventLog.txt" />

</log>

<database>

<add key="connectionString" value=[CONNECTION STRING HERE] />

</database>

<indexing>

<add key="hour" value="4" />

<add key="intervalType" value="daily" />

<--

<add value="hourBased" key="interval" />

<add value="2" key="intervalHours" />

-->

</indexing>

<indexRequestTimeOut>

<add key="seconds" value="5" />

</indexRequestTimeOut>

<indexService>

<add key="provider" value="IndexServer" />

</indexService>

<google>

<add key="licenseKey" value="[put your google license key here]" />

</google>

</Nata1>

And finally you need to add the exception management section adding your email address and a valid path where ASP.NET has permissions to write a file for the error log (this is also in SQL so you don't really need it)

<exceptionManagement mode="on">

<publisher assembly="Nata1" type="Nata1.Engine.Exceptions.ExceptionPublisher" exclude="*" include="Nata1.Engine.Exceptions.DataStructureException, Nata1; Nata1.Engine.Exceptions.QueryException, Nata1; Nata1.Engine.Exceptions.UIException" operatorMail=[YOUR EMAIL ADDRESS]filename=[YOUR FILE PATH eg.. c:/inetpub/wwwroot/SearchEngine/Nata1ErrorLog.txt] />

</exceptionManagement>

Now things would be working, but for a few bugs in the spider... so lets fix the spider before we implement it on our site. Open the file Engine/Indexing/IndexUtility.cs

First we need to up the  timeout on the HttpWebRequest.  Open the Engine/Normalization/SitePageUtility.cs… and around line 342 in the GetPage function, you will see a line that looks like this:

wr.Timeout=1;

Change it to 10000 as it is in milliseconds, and 1 will cause all spider pages to timeout.

We are going to need to change the default behavior of the spider.  It appears to have been designed to follow only relative links, which kept it on the specific site…  For .Text all of the links are absolute, so we need this utility to recognize and spider all links that are on the same domain as our base site.  This behavior can be changed in the file Engine/Indexing/IndexUtility.cs.  Update the buildSiteURLs function…  Actually just replace it with (careful on the word wrap the editor really messed up this function):

private static void buildSiteURLs(string url)

{

//_rawPages = new Hashtable();

// for debugging -

 

// this function will be just like get page urls

// 1. get the links for a page that don't appear in the root arraylist

// 2. add the unique URLs to the root arraylist

// 3. for each unique URL, recursivly call the function

// this function will eventually only return "unique" page urls

                 

// ok, capture all the URLs on the page

Regex rx = new Regex("href//s*=//s*(?:/"(?<href>[^/"]*)/"|(?<href>//S+))",

                        RegexOptions.IgnoreCase|RegexOptions.Compiled);

 

//Regex rx = new Regex("href//s*=//s*(?:(?:///"(?<url>[^///"]*)///")|(?<url>[^//s]* ))",RegexOptions.IgnoreCase|RegexOptions.Compiled);

 

//string hrefPattern = "<(a|A)//s{1}.*href=/"(?<href>[^/"]+)/"";

                  ArrayList pageResults = new ArrayList();

 

//Regex rx = new Regex(hrefPattern);

                  MatchCollection mc;

           

try

{

      // Perform the Regex Match

      string pageText = null;

      try

      {

            pageText = SitePageUtility.GetPage(url);

      }

      catch

      {

            // ok we've logged this

      }

      if(pageText != null)

      {

            _rawPages[url] = pageText;

      }

      else

      {

            return;

      }

      // System.Diagnostics.EventLog log = new System.Diagnostics.EventLog("vivaCostaRica");

      // log.WriteEntry("error requesting - " + url);

      // log.Close();

                       

      mc = rx.Matches(pageText);

                 

      foreach(Match m in mc)

      {

     

            Group g = m.Groups["href"];

            // prepare the url

            string linkTest = g.Value.ToUpper();

            //if(linkTest.IndexOf("/")!=0)continue; no need to check for relative vs static

            if(linkTest.IndexOf("/")<-1)continue; //Use this to strip anchors and some javascript

            if(linkTest.IndexOf(".JPG")>-1)continue;

            if(linkTest.IndexOf(".GIF")>-1)continue;

            if(linkTest.IndexOf(".PDF")>-1)continue;

            if(linkTest.IndexOf(".CSS")>-1)continue;

            //                      int testInt = linkTest.IndexOf(".jpg");

            string href = g.Value;

                             

            if(_debug == true)

                  LogUtility.LogEvent(EntryType.Info , DateTime.Now, "href : " + href);

                             

            if(href.IndexOf("/")==0)

                  href = SiteUtility.GetSiteBaseUrl() + href.Substring(1); //only append the base if it is a relative link

            string uri = href.Split(char.Parse("#"))[0].ToString(); //strip any anchor tags

            //    string defaultPage = getSiteDefaultPage();

            // ADD SUPPORT FOR DIFFERENT EXTENSTIONS

                              if(!_siteUrls.Contains(uri)&&uri!=SiteUtility.GetSiteBaseUrl()&&uri!=(SiteUtility.GetSiteBaseUrl()+SiteUtility.GetSiteDefaultPage())&&uri.IndexOf(SiteUtility.GetSiteBaseUrl())==0)

            {

                                    //if(_debug==true&&_siteUrls.Count<6||_debug==false)

            {

                  _siteUrls.Add(uri);

                  pageResults.Add(uri);

            }

                       

            }

            else if(_debug == true)

            {

                  //log why the URL was not added

                  if(_siteUrls.Contains(uri))

                        LogUtility.LogEvent(EntryType.Info , DateTime.Now, "The URL has already been added to the list");

                                    if(uri.IndexOf(SiteUtility.GetSiteBaseUrl())!=0)

                                          LogUtility.LogEvent(EntryType.Info , DateTime.Now, "The URL is off of the host domain");

                                    if(uri==SiteUtility.GetSiteBaseUrl()||uri==(SiteUtility.GetSiteBaseUrl()+SiteUtility.GetSiteDefaultPage()));

                                          LogUtility.LogEvent(EntryType.Info , DateTime.Now, "The URL is for the default page, and is already indexed");

 

            }

      }    

      LogUtility.LogEvent(EntryType.Info , DateTime.Now, "RegEx URL Matches for this page : " + mc.Count.ToString());

      LogUtility.LogEvent(EntryType.Info , DateTime.Now, "pageResults for this page : " + pageResults.Count.ToString());

      // now for each unique link on this page make a recursive call

      // TESTING - make sure we only have unique URLs

                 

}

catch(Exception ex)

{

                        LogUtility.LogError(EntryType.RecoverableError,DateTime.Now,"Error processing page " + url,ex);

 

      //throw new ApplicationException("error occured building Site Urls", ex);

 

}

//if(_debug == true)

//    if(this.siteURLs.Count>5)return;

 

foreach(string s in pageResults)

{

      buildSiteURLs(s);

}

                 

                 

}

 

While we are here there is a bug in the SearchResults Repeater designer, I didn't find it because I wanted to implement the whole thing as a class in my application directly and avoid all of the carefully crafted but not documented server controls.  But I devised this workaround...  There is a problem with the ItemTemplate object, but without it your repeater wont return results... the solution is to use the alternatingItemTemplate...  So in the file UI/Common/BaseRepeater.cs find the line around 460 that reads:

// don't do anything if no ItemTemplate

if (_itemTemplate == null)

      return;

and change it to:

// don't do anything if no ItemTemplate

if (_itemTemplate == null && _alternatingItemTemplate == null)

      return;

else if(_itemTemplate == null)

      _itemTemplate = _alternatingItemTemplate;

 Now we are ready to build NATA1 and add a reference to the DLL to your web site project and to your toolbox in VS.NET (Warning.  Make a new tab, it will add lots of new controls) Following the instructions from the authors original article:

Step 3. Add Nata1.dll to your toolbox.  Right click your toolbox.  Choose “add/remove items” , click browse, and find Nata1.dll.  Nata1 controls are now added to your toolbox.

there are dozens of controls, some are container controls, like ResultsRepeater, and other are for individual Items, all the ones with a smiley icon are placed in the Item or Alternating Item template, like HitUrl, HitWords, etc.  You can get creative with your toolbox icons, I've included some neat ones like Homestar runner icons.  Controls like QueryTime sit in the header template.  Some controls are specific to a search provider, e.g. Google has many controls, like spelling suggestions, but index server only has a couple so you have to be careful to make sure the provider supports the controls.

 After adding the reference, add the following line to your Application_Start function in your global.asax

      protected void Application_Start(Object sender, EventArgs e)

            {

                  Nata1.Controller.Start();

            }

Now when your site starts, it will check the SQL logs to see when it was last spidered, and it should begin crawling your site.  You should see activity in the log, and after a while you should have a decent collection of site pages in your database.  Now we just need to build a search page…  (some of this content is from the original FAQ)  just make a page called search.aspx for now and follow the Authors original step 4:

Step 4: We'll need a form to get from a search box to the search results page.  Go ahead and drag and drop “SearchForm“ (control with the ducky) onto any ascx or aspx page in your site. 

To use an image, set the SearchButtonText to an image Url (I know, not the most elegant) or enter text and make sure to set the ButtonType as well as SearchPageUrl.  As you can see, there is a bug in the designer as the image isn't updating.

 

And then for step five make a page called SearchResults.aspx, you will need to link it to the control you added in step 4. and follow the Authors instructions:

Step 5: We'll build the search results page.  Drag and drop “Search Results Repeater” (the one with the fairy icon) onto a ascx or aspx page

The two most import properties will be “Query Provider“ - here you want to select Nata1.  The other property is called SearchQueryTemplate mode, here you want to select simple.

Then finally we follow the Authors Step 6.

 

 

Step 6: Right click the template, choose the template you want to edit, and start dragging and dropping controls.

Here I dragged the controls SearchQuery and TotalHits onto the Header template, and put an ad banner there too, you can rotate based on keyword if you want.

There are several other templates you'll need to set, like NoResults, etc. There's also a template for a Search Form, and you can specify what search form controls to place there, perhaps you want an advanced search form to be at the top.

The key is in that last part…  Earlier I noted that the Repeater relies on the ItemsTemplate row, but if you add that to the control, it breaks…  so we are going to want to add some basic output to the alternating items row… go to your HTML and add…

 

<AlternatingItemTemplate>

<P>

      <nata1searchui:HitTitle id="HitTitle1" runat="server"></nata1searchui:HitTitle>

      <nata1searchui:HitRankingIcon id="HitRankingIcon1" runat="server"></nata1searchui:HitRankingIcon></P>

<P>

      <nata1searchui:HitPageWords id="HitPageWords1" runat="server"></nata1searchui:HitPageWords></P>

<P>

      <nata1searchui:HitCategories id="HitCategories1" runat="server"></nata1searchui:HitCategories></P>

</AlternatingItemTemplate>

 

As well as an error handler, which cannot be set from the UI…

 

 <ErrorTemplate>

An error has occured and our support staff has been notified.

</ErrorTemplate>

 

And with this, You should be able to search through the site pages in your database.. Not to pretty, but really cool, because if you made it this far you are hard core, and understand the power of what just happened on your site…  you might want to explore the controls for the admin area… and add some noise words to your database too.  Happy searching….

源码直接下载地址: https://pan.quark.cn/s/a4b39357ea24 在信息技术领域中,开发一个模仿微信客服交流平台的界面是一项普遍的需求,尤其是在构建企业级沟通工具时。这个名为"仿微信客服交流界面(具备聊天信息本地数据库存储功能)"的项目,致力于为用户创造一个类似于微信的互动体验,并且已经完成了聊天信息在本地数据库中的保存功能,以此保障信息的安全性和可恢复性。另外,项目还包含了网络传输的代码,旨在帮助开发者更好地理解和将此功能整合进自己的应用程序中。 现在让我们深入探究聊天界面的构建过程。微信客服交流界面通常由以下几个核心组件构成:用户个人照片、昵称展示、消息展示气泡、时间标记、输入区域以及发送控制键。这些组件需要经过细致的排布,以确保界面既清晰又便于使用。在用户界面设计方面,一般会采用 Material Design 或者 iOS 的 Human Interface Guidelines 来设计符合平台标准的界面。源代码文件 ChatUIDemo 可能包含了这一界面实现的代码,开发者可以通过查看和调整这个文件来个性化自己的聊天界面。 聊天信息在本地数据库中的存储是一项核心功能。在该项目中,或许选用了SQLite作为轻量级数据库,因为它易于集成,支持事务处理,适合存储结构化的数据,例如用户标识符、接收者标识符、消息内容、发送时刻等。通过运用SQL指令,能够执行数据的增加、删除、修改和查询操作,从而确保聊天记录的完整性和一致性。开发者可能需要关注如何将新接收到的消息添加到数据库中,以及如何从数据库中获取历史记录并在界面上进行展示。 在网络传输方面,可能通过HTTP或HTTPS协议来实现,并且使用了诸如AFNetworking(iOS)或O...
内容概要:本文围绕虚拟同步发电机(VSG)接入弱电网的序阻抗建模与稳定性分析开展研究,基于Matlab/Simulink平台搭建详细的仿真模型,系统复现并验证相关理论方法。研究重点包括VSG在弱电网条件下的正负序阻抗特性建模、基于小信号分析的扫频法建模流程、系统阻抗交互特性及潜在的失稳机理分析。通过具体仿真案例,深入探讨了VSG控制参数对系统稳定性的影响,旨在为新能源并网系统的稳定运行提供理论依据与技术支撑。该内容属于电力电子与电力系统稳定性交叉领域的前沿课题,具有重要的学术价值与工程应用前景。; 适合人群:具备电力系统分析、电力电子变换器控制等基础知识,熟悉Matlab/Simulink仿真环境,从事新能源并网、微电网控制、电力系统稳定性研究的研究生、科研人员及工程师;有志于复现高水平期刊论文中阻抗建模与稳定性分析方法的技术开发者。; 使用场景及目标:① 掌握虚拟同步发电机在弱电网中的序阻抗建模理论与实现方法;② 理解并实践基于扫频法的小信号稳定性分析全过程;③ 应用于构网型变流器、虚拟同步机等先进并网技术的稳定性研究与仿真验证。; 阅读建议:建议结合所提供的Simulink仿真模型与技术资料,按照文档结构循序渐进地学习,重点关注建模原理、仿真参数设置与结果分析过程,同时参考链接中的完整资源进行代码调试与深入探究。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值