65.9K
CodeProject 正在变化。 阅读更多。
Home

OmniSearch(Google 缓存引擎)

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.60/5 (5投票s)

2003年2月11日

4分钟阅读

viewsIcon

104145

downloadIcon

2334

OmniSearch 尝试通过缓存搜索来减少对 Google Web 服务的访问次数。

引言

OmniSearch 项目的成立宗旨是设计一个可定制的搜索引擎,可以无缝集成到任何运行 ASP.NET 框架的网站中。OmniSearch 通过缓存 Google API 的结果,并使用 XSL 显示经过处理的 XML 文件来实现这一目标。这将为管理员提供灵活性和易于编程的优势。

OmniSearch 将使用 Google API 作为 OmniSearch 引擎的后盾,它将完成应用程序的大部分处理工作。OmniSearch 完全可查询的统计引擎将收集用户的点击习惯,供网站管理员日后分析。OmniSearch 引擎将承担多种功能,包括但不限于:

  • 维护点击记录的统计数据
  • 缓存来自 Google XML SOAP API 的搜索结果
  • 为移动用户提供无线 WAP 接口,让他们能够利用 OmniSearch
  • 提供组件,集成到网络管理员可能正在运行的现有 ASP.NET 项目中

背景

该项目的主要目标是克服 Google API 对用户施加的限制,该限制每天只允许 1000 次访问。我们的团队计划通过将 Google API 的序列化结果缓存到 XML 文件中来绕过此限制。后续的网页搜索将首先查询 XML 缓存,以查找能够满足当前用户当前查询的先前搜索结果。通过利用缓存,OmniSearch 在被网站用户使用得越多时,将变得更快,更能处理用户搜索请求。

作为网站管理员,最难收集的就是关于用户网站习惯的有用信息。为了进一步挑战 OmniSearch 团队,我们决定添加一个点击日志功能,该功能将使管理员能够查看可能负载很高的页面。这也有助于减少查找某些页面的时间,因为管理员将能够告诉用户一些信息,例如“当日最佳网站”、“本月热门 5 个网站”等。

除了缓存的搜索结果和统计数据库之外,OmniSearch 还将支持搜索引擎的 WAP 接口。通过使用 ASP.NET Mobile Architecture,OmniSearch 团队能够提供一个无线接口,该接口会根据正在使用的无线浏览器进行自定义。

Using the Code

在一切正常工作之前,需要在 web.config 文件中设置以下参数。

<!-- application specific settings -->
<appSettings>
    <!-- Realative Location of Cache -->
    <add key="CacheLocation" value="\cache" />
    <!-- Directory Name of Website -->
    <add key="DirectoryName" value="\OmniSearch" />
    <!-- Static Location of Website -->
    <add key="WebSiteLocation" value="D:\Websites\Development\OmniSearch" />
    <!-- Proxy Settings if needed -->
    <!-- Set a host to use as an HTTP proxy. If unset, 
        GoogleSearch will also check the 
        system properties and use those values. If those 
        are also unset, HTTP requests 
        go direct with no proxy.
    -->
    <add key="ProxyHost" value="" />
    <!-- Set a port to use as an HTTP proxy. 
        Only used if proxyHost is also set. If 
        unset, port 80 is assumed to be the default.
    -->
    <add key="ProxyPort" value="" />
    <!-- Set the username required for the HTTP proxy. 
      Only used if ProxyHost is also set. -->
    <add key="ProxyUsername" value="" />
    <!-- Set the password required for the HTTP proxy. 
      Only used if ProxyHost is also set. -->
    <add key="ProxyPassword" value="" />
    <!-- Google Configuration Information -->
    <!-- Set the user key used for authorization by 
        Google SOAP server. This is a 
        mandatory attribute for all requests.
        A key can be obtained from 
        http://www.google.com/apis/index.html
    -->
    <add key="GoogleKey" value="" />
    <!-- Set the maximum number of results to be returned.  
        The number must be between 1 and 10 
    -->
    <add key="GoogleMaxReturn" value="10" />
    <!-- Enable or disable the "related-queries" filter.
        Must be [True | False]
    -->
    <add key="GoogleFilter" value="False" />
    <!-- Set the restrict. 
        This allows you to restrict the search to 
        a specific document store such as 
        "Penn State", "IST" or any argument that can 
        be used in a normal Google Search.
    -->
    <add key="GoogleRestrict" value="" />
    <!-- Enable or disable SafeSearch. When SafeSearch 
        is turned on, sites and web pages 
        containing pornography and explicit sexual 
        content are blocked from search 
        results. While no filter is 100% accurate, 
        Google's filter uses advanced 
        proprietary technology that checks keywords 
        and phrases, URLs and Open Directory 
        categories.
        Must be [True | False]
    -->
    <add key="GoogleSafeSearch" value="False" />
    <!-- Domain to search -->
    <add key="DomainToSearch" value="ist.psu.edu" />
    <!-- Number of days the cache will stay in memory -->
    <add key="ExpireTime" value="5" />
</appSettings>

以下是一个 XSL 文件示例,可以针对 Google Web Service 序列化的 XML 缓存搜索使用。此 XSL 文件显示搜索内容,就像您在 Google 搜索页面上看到的那样。在源代码中,此文件名为 searchresults.xsl

<?xml version="1.0" encoding="utf-8" ?>
<xsl:stylesheet version="1.0" 
   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" version="4.0" 
   encoding="iso-8859-1" indent="yes" />
<xsl:template match="/">
    <xsl:apply-templates select="GoogleSearchResult" />
</xsl:template>
<xsl:template match="GoogleSearchResult">
    <table width="100%" border="0" cellspacing="0" 
        cellpadding="0" bgcolor="#6699cc" 
        style="padding: 5px, 5px, 5px, 5px; margin-top: 5px;" ID="Table1">
        <tr style="color:white;">
            <td aling="left">Search <b>ist.psu.edu</b> for <b>
                    <xsl:value-of select="searchQuery" />
                </b></td>
            <td align="right">Results <b>
                    <xsl:value-of select="startIndex" />
                </b> - <b>
                    <xsl:value-of select="endIndex" />
                </b> of about <b>
                    <xsl:value-of select="estimatedTotalResultsCount" />
                </b>.</td>
        </tr>
    </table>
    <table border="0" cellspacing="0" cellpadding="0" ID="Table2">
        <xsl:for-each select="resultElements/ResultElement">
            <tr>
                <td>
                    <b>
                        <a style="color:blue;" 
                               href="/OmniSearch/forward.aspx?url={URL}">
                            <xsl:value-of select="title" />
                        </a>
                    </b>
                </td>
            </tr>
            <tr>
                <td>
                    <xsl:value-of select="snippet" />
                </td>
            </tr>
            <tr>
                <td>
                    <span style="color:green;"><xsl:value-of select="URL" />
                        - <xsl:value-of select="cachedSize" /></span>
                    <a style="color:gray;" 
                       href="http://216.239.53.100/search?
                           q=cache%3A{URL}+{searchQuery}">
                    Cached</a>
                    <a style="color:gray;" 
                       href="http://www.google.com/
                          search?q=related%3A{URL}">
                    Similar pages</a>
                </td>
            </tr>
            <tr>
                <td>
                    <br />
                </td>
            </tr>
        </xsl:for-each>
    </table>
    <table width="100%" border="0" cellspacing="0" 
                         cellpadding="0" bgcolor="#6699cc" 
        style="padding: 5px, 5px, 5px, 5px; margin-top: 5px;" ID="Table3">
        <tr style="color:white;">
            <td align="left">
                <b>
                    <a style="color:white;" 
                       href="/OmniSearch/search.aspx?search=
                           {searchQuery}&back={startIndex}">
                        « Back</a>
                </b>
            </td>
            <td align="right">
                <b>
                    <a style="color:white;" 
                        href="/OmniSearch/search.aspx?
                           search={searchQuery}&forward={endIndex}">
                        Next »</a>
                </b>
            </td>
        </tr>
    </table>
</xsl:template>
</xsl:stylesheet>

以下代码是实现 OmniSearch 引擎到任何 ASP.NET 网页所需的全部代码。这花费了很多时间,但我希望它既易于使用,又非常强大。

protected System.Web.UI.WebControls.Xml resultsXml;      
        
private void Page_Load(object sender, System.EventArgs e)
{
    search = new SiteSearch(Request.QueryString["search"]);

    // if there is no start query then the program assumes that
    // it wants to start the search at the beginning
    if (Request.QueryString["forward"] == null && 
                   Request.QueryString["back"] == null)
        start = 1;
    else if (Request.QueryString["forward"] != null && 
                   Request.QueryString["back"] ==  null) 
        start = Convert.ToInt32(Request.QueryString["forward"]) +1; 
    else if (Request.QueryString["forward"] == null && 
                   Request.QueryString["back"] != null)
        start =  Convert.ToInt32(Request.QueryString["back"]) - 
             Convert.ToInt32
            (ConfigurationSettings.AppSettings["GoogleMaxReturn"]);
    else
        start = 1;
        
    if(start <  1)
        start = 1;

    resultsXml.DocumentSource = search.DoSearch(start);
}

这是将所有内容整合在一起后,ASP.NET 页面可能是什么样子的一个例子。下面的代码行是您在任何 ASP.NET 应用程序中实现 OmniSearch 引擎真正需要的所有代码。

<asp:xml id="resultsXml" runat="server" 
    TransformSource="searchresults.xsl"></asp:xml>

关注点

在实现此代码时,我学到了几个主要知识点,它们列示如下:

  • Google Web Service 非常强大,但除了每天 1000 次访问之外,还有许多限制。
  • XML 序列化的使用对完成此项目非常有用。
  • XSL 及其在 .NET 中的用法,即使客户端浏览器不支持 XSL。
  • 为了绕过命名 XML 缓存文件时的一些障碍,我不得不使用搜索查询的 MD5 值,并在 MD5 值末尾加上一个索引号,用于特定的页面。当文件写入 /cache 目录时,其格式为 [搜索查询(MD5 值)].[页面索引].xml

在使用 OmniSearch 之前,需要做的一件事。

  • 需要将缓存目录 /cache 的完全访问权限授予 [计算机名]\ASPNET。这样做是为了让 OmniSearch 能够将 XML 缓存文件写入该目录。

我最终会将此引擎集成到我同时开发的 OmniPortal 项目中。有关 OmniPortal 的更多信息,请访问 Source Forgehttp://beta.omniportal.net/(老王卖瓜,自卖自夸)。

历史

  • 2003 年 2 月 10 日 - 首次发布

许可证

本文未附加明确的许可证,但可能在文章文本或下载文件本身中包含使用条款。如有疑问,请通过下面的讨论区联系作者。

作者可能使用的许可证列表可以在此处找到。

© . All rights reserved.