Search Server 2008にGoogle検索を追加する

ページ : 1 2
<この記事を全て表示する場合はこちらをクリック>

0015

Search Server 2008にGoogle検索を追加する方法について記載します。

ただし自分の確認した環境では、検索する文字列によりレスポンスが物凄く遅いです。
この点が解決出来なければ、企業内で利用するのは難しいかもしれません。

こちら遅い件、解決しました。
ソースは修正して元のモノと差し替えてあります。
※ただし検索結果が0件だったり、いろいろ動かない条件がありますので、その場合は修正して利用してください。

フェデレーション検索用定義ファイルのダウンロード

Andrew WoodwardさんのWEBサイトから”MSS 2008 – SUGUK Jan 10 2008.zip”をダウンロードします。

Search Server 2008: Federated sites that do not return XML
http://www.21apps.com/sharepoint/search-server-2008-federated-sites-that-do-not-return-xml/

フェデレーション検索用定義ファイルのインポート

0022

検索サーバーの検索管理にアクセスし、クエリと結果のフェデレーション場所を開きます。

0032

場所のインポートを選択し、”Google.FLD”を読み込みます。

場所の編集

0042

“場所の編集”を選択します。

0052

“場所情報 > クエリ テンプレート”のサーバ名を検索サーバのサーバ名に変更します。

例えばサーバ名が”serv30″の場合には以下のように入力します。

http://serv30/_layouts/search/google.aspx?q={searchTerms}

“[その他の結果] リンク テンプレート”を以下の文字列に変更します。

http://www.google.co.jp/search?hl=en&q={searchTerms}

“制限および資格情報”の”資格情報の指定”には以下を選択します。

NTLM – アプリケーション プール ID を使用する

最後に”OK”を選択し、設定を保存します。



XML生成用ファイルの設置

検索サーバの、以下のディレクトリにフォルダ”SEARCH”を作成します。

C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\

さらにその中に”Google.aspx”と”Google.aspx.cs”を保存し、”Google.aspx.cs”の中身を以下の文字列で上書きします。
※Googleの検索結果が変更になった場合、動作しなくなる可能性がありますのでご注意を。

using System;
using System.Data;
using System.Net;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

public partial class _Default : System.Web.UI.Page
{
    protected string query;

    protected void Page_Load(object sender, EventArgs e)
    {
        query = Request.QueryString["q"];
    }

    protected override void Render(HtmlTextWriter writer)
    {
        StringBuilder sb = new StringBuilder();

        Response.ContentType = "text/xml";
        sb.Append("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
        sb.Append("<rss version=\"2.0\">");
        sb.AppendFormat("<channel><title><![CDATA[Google: {0}]]></title><link/><description/><ttl>60</ttl>", query);
        sb.Append(getRssItemXml(query));
        sb.Append("</channel></rss>");

        writer.Write(sb.ToString());
    }

    private string getRssItemXml(string query)
    {
        string url = string.Format("http://www.google.co.jp/search?q={0}", query);

        WebRequest myrequest = HttpWebRequest.Create(url);
        myrequest.Method = "GET";

        // レスポンスデータ取得
        string strData;
        using (WebResponse myresponse = myrequest.GetResponse())
        using (StreamReader reader = new StreamReader(myresponse.GetResponseStream(), System.Text.Encoding.Default))
        {
            // データ取得
            strData = reader.ReadToEnd();
        }
        Regex searchCountPattern = new Regex("の検索結果 約 <b>(.+?)</b> 件中 <b>([0-9]+?)</b> - <b>([0-9]+?)</b> 件目");
        Regex searchPattern = new Regex("<li class=g><h3 class=r><a href=\"(?<link>.*?)\"(.*?)>(?<title>.*?)</a>(.*?)</h3><div class=\"s\">(?<desc>.*?)<br><cite>", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Multiline);
        StringBuilder sb = new StringBuilder();

        int endpos = 10;
        if (searchCountPattern.IsMatch(strData))
        {
            Match match = searchCountPattern.Match(strData);
            if (match.Groups.Count == 3)
            {
                endpos = Convert.ToInt32(match.Groups[2]) - (Convert.ToInt32(match.Groups[1]) - 1);
            }
        }
        int i = 0;
        foreach (Match m in searchPattern.Matches(strData))
        {
            sb.AppendFormat("<item><title><![CDATA[{0}]]></title><link><![CDATA[{1}]]></link><description><![CDATA[{2}]]></description></item>", m.Groups["title"].Value, m.Groups["link"].Value, m.Groups["desc"].Value);
            i++;
            if(i >= endpos)
            {
               break;
            }
        }

        return sb.ToString();
    }

}

2009年2月7日追記

searchPatternを以下に変更すると早くなった気がするんだけど・・・どうでしょうか。
でも根本的にどこが原因なのか分かってません。

Search Server 2008の検索結果にキャッシュとかの表示は必要ないのかなと思い、その部分を削ってみました。

Regex searchPattern = new Regex("<li class=g><h3 class=r><a href=\"(?<link>.*?)\"(.*?)>(?<title>.*?)</a>(.*?)</h3><div class=\"s\">(?<desc>.*?)<br><cite>");

動作確認

0062

以下のサイトにアクセスし、検索結果が正常に出力されているか確認します。

http://<サーバ名>/_layouts/search/google.aspx?q=<検索文字列>

正常に出力されていれば、これで設定完了です。

Search Server 2008へパーツとして組み込み

0082

サイトの操作権限のあるアカウントで検索結果画面にアクセスし、”ページの編集”を選択します。

0101

“WEBパーツの追加”を選択し、”フェデレーション検索結果”にチェックを入れ、”追加”を選択します。

011

“共有WEBパーツの変更”を選択します。

012

“場所”の選択で”Google”を選択し、”OK”を選択します。

013

“編集モードの終了”を選択し、完了です。

既知の問題点

英数字を検索すると結果が返ってくるのが早いのですが、2バイト文字を検索するとたまに激しく重い上にCPUリソースの使いっぷりが凄まじくなります。

例えば”フェデレーション”で検索するととても高速ですが、”自転車”と検索すると反応が返ってくるまでに30秒くらいかかってしまいます。

こちら何かご存じの方いらっしゃれば是非教えてください。

遅い件、解決しました。

参考リンク

Search Server 2008: Federated sites that do not return XML
http://www.21apps.com/sharepoint/search-server-2008-federated-sites-that-do-not-return-xml/

ページ : 1 2
<この記事を全て表示する場合はこちらをクリック>

1 2

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です