使ってみよう! Bing API/SDK

第22回使ってみよう! Bing API─⁠─Silverlight編(2)

はじめに

今回もSilverlightからBing APIを使ってみましょう。

4月12〜14日に、ラスベガスでMicrosoftの開発者やデザイナー向けのカンファレンスMIX11が開催されました。MIX11でSilverlightの新しいバージョン、Silverlight 5 Betaが公開されています。今回もSilverlightを使用しますので、せっかくなのでSilverlight 5 Betaの内容にも少しふれた内容にしています。残念ながら、注目度の高い3Dやサウンド関連の機能にはふれていません。ちなみにMIX11ではBingに直接関連する発表や内容はありませんでした。

開発環境

開発環境については、前回を参照してください。Visual Studio 2010(またはVisual Web Developer Express 2010Silverlight 4 Tools for Visual Studio 2010を使用します。また、Rx for Silverlight 4も非同期通信処理に使用します。

Silverlight 5 Beta

Silverlight 5 Betaを使用する場合、次の手順でインストールを行ってください。

  1. Visual Studio 2010 Service Pack 1をインストールしていない場合、インストールします。

  2. Silverlight 5 Beta Tools for Visual Studio 2010 Service Pack 1をインストールします。

  3. Silverlight 5 Betaを対象としたExpression Blend Preview for Silverlight 5も公開されています(英語版のみ⁠⁠。連載では使用しませんが、ぜひこちらも体験してみてください。

アプリケーションの作成

それでは、Silverlightアプリケーションを作成しましょう。Silverlightアプリケーションプロジェクトの作成からBing APIのサービスの参照までについても、前回を参照してください。次のことを順に行っていました。今回も言語はVisual Basicを使用します。

  • Silverlightアプリケーションプロジェクトの作成(Visual Basic)
  • ライブラリーの参照を追加
  • Bing APIサービスの参照を追加

Silverlight 5 Betaをインストールしていると、プロジェクト作成時に選択できるSilverlightのバージョンにSilverlight 5が追加されています。ここまで完了すると、プロジェクトでBingPortTypeClientというクラスが自動生成され、利用可能な状態になります。

画面作成とコードの記述

前回に作成したWebサイトの検索と同等のアプリケーションのひな形を作成します。前回の内容も併せて参照してください。

画面は、次のようなXAMLのコードを記述します。<Grid>要素部分のみ示しています。

MainPage.xaml
<Grid x:Name="LayoutRoot" Background="White">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition Width="Auto" />
        </Grid.ColumnDefinitions>
        <TextBox x:Name="QueryTextBox" Margin="5" />
        <Button x:Name="SearchButton" Grid.Column="1" Margin="5" Width="80"
                Content="検索" />
    </Grid>
    <ListBox x:Name="ResultListBox" Grid.Row="1" Margin="5">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Title}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</Grid>

続いて、API呼出しや表示設定を行うコードです。

MainPage.xaml.vb
Partial Public Class MainPage
    Inherits UserControl

    Public Sub New()
        InitializeComponent()
        AddHandler SearchButton.Click, Sub() Search(QueryTextBox.Text)
    End Sub

    Private Sub Search(ByVal query As String)
        If query = "" Then
            ' クエリーが指定されていない場合は処理を抜ける
            Exit Sub
        End If

        Dim client = New BingPortTypeClient

        ' (ここに Bing API の呼び出し処理を記述)

    End Sub
End Class

以上で準備完了です。

ニュースの検索

第19回から第21回までにBing APIを利用したWebサイト検索、画像検索、動画検索、関連キーワードの取得について紹介しています。これ以外にも、ニュース検索、キーワードの修正候補の取得も可能です[1]⁠。まずは、ニュースを検索してみましょう。

Bing APIによるニュース検索は、日本では使用できない機能も一部ありますが、日本語の検索クエリーで日本語のニュース検索が可能です。

リクエストの作成

ニュース検索のリクエストを生成し、APIを呼び出すコードは次のようになります。

' SearchRequest と NewsRequest の生成
Dim request = New SearchRequest With {
    .AppId = "AppID",
    .Market = "ja-JP",
    .Query = query,
    .Sources = {SourceType.News},
    .News = New NewsRequest With {
        .SortBy = NewsSortOption.Date,
        .Count = 10}
}

' API 呼び出し
client.SearchAsync(request)

SearchRequestのSourcesプロパティにSourceType.Newsを指定し、NewsプロパティにNewsRequestオブジェクトを指定しています。

NewsRequestオブジェクトを使用して、さらに細かな検索条件の指定が可能です。コードではSortByプロパティを使用して、新しいニュースから取得するよう指定しています。NewsSortOption.Dateの代わりにNewsSortOption.Relevanceを指定するとクエリーと関連性の高い順にニュースを取得します(規定の動作⁠⁠。SortBy以外にもCategoryプロパティなどが用意されていますが、日本のニュースには対応していないため割愛します。

また、米国を対象とした場合(Marketプロパティにen-usを指定⁠⁠、Queryプロパティに何も指定せずに検索するとトップニュースが取得できます。

レスポンスの取得

APIの呼び出しが完了し、ListBoxにニュース検索結果を表示するコードを記述します。リクエスト生成処理の前に追記してください。

' API 呼出し完了したときの処理(リストボックスに結果を表示)
Observable.FromEvent(Of SearchCompletedEventArgs)(client, "SearchCompleted") _
    .Take(1) _
    .Subscribe(
        Sub(e)
            If e.EventArgs.Error Is Nothing Then
                Dim result = e.EventArgs.Result
                ResultListBox.ItemsSource = If(result.News IsNot Nothing, result.News.Results, Nothing)
            End If
        End Sub)

News.Resultsコレクションに、各ニュースの検索結果NewsResultオブジェクト)が格納されています。扱っているデータはことなりますが、処理内容はほぼ前回と同じです。

NewsResultクラスのプロパティは次のとおりです。

名前 説明
BreakingNews 速報であれば1、それ以外は0
Date ニュースがインデックス化された日付(文字列)
NewsCollections ニュースに関連した情報
NameプロパティとNewsArticlesコレクションプロパティを持っています。
Snippet ニュース記事の抜粋
Source ニュースの配信元
Title タイトル
Url ニュース記事へのURL

NewsCollectionsプロパティによって、ニュースに関連した写真や文章をさらに参照ができます。ただし、日本では対応していないようです。NewsCollections.NewsArticlesコレクションにはNewsArticlesオブジェクトが格納されており、NewsArticelsオブジェクトは、NewsResultと同様にDate、Snippet、Source、Title、Urlプロパティを持っています。

さて、実行結果を見てみましょう。XAMLではTitleプロパティのみ表示するように記述していましたので、結果は図1のようになります。

図1 実行結果 ニュースの検索
図1 実行結果 ニュースの検索

ニュースの関連キーワードの表示

実は、ニュース検索の場合、ニュース検索結果だけではなく、検索クエリーに関連するキーワードがある場合、その情報も一度に取得できています。

キーワードを表示するには、ListBoxのItemsSourceプロパティに設定している部分を次のように変更してみてください。

ResultListBox.ItemsSource = If(result.News IsNot Nothing AndAlso
                               result.News.RelatedSearches IsNot Nothing,
                               result.News.RelatedSearches, Nothing)

関連キーワードはNews.RelatedSearchesコレクションに格納されています。キーワードを表すNewsRelatedSearchクラスはTitleとUrlプロパティのみ持っています。

実行結果は図2のようになります。

図2 実行結果 関連キーワードの表示
図2 実行結果 関連キーワードの表示

Bingのニュース検索図3に表示される関連キーワードと同等の内容が取得できています。同じクエリーでも取得できる関連キーワードは頻繁に変わるようです。

図3 Bing ニュース
図3 Bing ニュース

キーワードの修正候補の取得

もうひとつソースを紹介しましょう。検索ではありませんが、検索クエリーの修正候補(Bingでは「推奨キーワード⁠⁠)の取得も可能です。Webサイトの検索などと組み合わせて使います。

リクエスト生成部分のコードは次のようになります。SourcesプロパティにSourceType.Spellを指定します。

Dim request = New SearchRequest With {
    .AppId = "AppID",
    .Market = "ja-JP",
    .Query = query,
    .Sources = {SourceType.Spell, SourceType.Web},
    .Web = New WebRequest
}

レスポンス処理は次のように変更します。

ResultListBox.ItemsSource = If(result.Spell IsNot Nothing, result.Spell.Results, Nothing)

修正候補を表すSpellResultクラスは、Valueプロパティのみ持っています。名前がTitleではありませんので、このまま実行しても何も表示されません。XAMLの<TextBlock>要素を次のようにValueプロパティを表示するよう変更します。

<TextBlock Text="{Binding Value}" />

実行結果は図4の通りです。

図4 実行結果 修正候補の取得
図4 実行結果 修正候補の取得

複数種類のデータの表示

Bing APIを利用すると、さまざまな検索ができ、Webサイトや画像、ニュースやキーワードの修正候補などさまざまな結果を得ることができます。それらを表示するために、これまではXAMLの<ListBox>要素の部分を編集し、それぞれの結果に合わせたListBoxを作成していました。言い換えると、検索対象を変更するとListBoxも変更する必要がありました。

そこで、Silverlight 5 Betaの新しいImplicit Data Templateという機能を使用してみましょう。これは以前からWPFでは使用できた内容です。データの型に応じた表示方法(テンプレート)を定義しておくことで、何も指定がない場合、そのテンプレートを使用するという機能です。

ListBoxのItemsSourceプロパティに指定したコレクションの内容は、何もテンプレートの指定がない場合、コレクションの各オブジェクトのToStringメソッドを呼んだ結果がListBoxに表示されます図5

図5 テンプレートを指定していな場合の表示
図5 テンプレートを指定していな場合の表示

もし型に対するテンプレートを定義していれば、文字列ではなくそのテンプレートを使用して表示されます。この仕組みを使うと、ListBox内にWebサイトの結果や修正候補など異なる型のデータが含まれていた場合も、それぞれのデータに合わせた表示が可能になります。

さっそくコードを修正してみましょう。まず、XAMLの<ListBox>要素部分は以下のように変更し、これまで記述していたテンプレート表記を削除します。

<ListBox x:Name="ResultListBox" Grid.Row="1" Margin="5" />

次に、<UserControl>要素に名前空間を追加します。値は環境によって異なります。連載の通りにアプリケーション プロジェクトを作成していた場合は次のようになります。BingApiSampleはプロジェクト名から自動で付けられた名前空間、ServiceReferenceはWebサービスの参照の追加時に指定した名前空間です。

xmlns:ref="clr-namespace:BingApiSample.ServiceReference"

そして、型ごとのテンプレートを定義します。ここではWebサイトの検索結果(WebResult)および修正候補(SpellResult)のテンプレートを記述します。次のコードを<UserControl>要素内に追加します。

<UserControl.Resources>
    <!-- 修正候補のテンプレート -->
    <DataTemplate DataType="ref:SpellResult">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="修正候補:" />
            <TextBlock Text="{Binding Value}" Margin="5 0 0 0" />
        </StackPanel>
    </DataTemplate>
    
    <!-- Web サイト検索結果のテンプレート -->
    <DataTemplate DataType="ref:WebResult">
        <HyperlinkButton NavigateUri="{Binding Url}" Content="{Binding Title}" TargetName="_blank" />
    </DataTemplate>
</UserControl.Resources>

ポイントは、DataType属性で型を指定している部分です。ListBoxに指定したコレクションの各要素のオブジェクトが、ここで指定した型と一致する場合、このテンプレートが使用されて表示されます。

検索処理のコードも変更します。レスポンス処理で、ItemSourceプロパティにコレクションを設定していたところを、次のようにWeb検索結果と修正候補との両方合わせたコレクションを設定します。

Dim list = New List(Of Object)
If result.Spell IsNot Nothing Then
    list.AddRange(result.Spell.Results)
End If
If result.Web IsNot Nothing Then
    list.AddRange(result.Web.Results)
End If
ResultListBox.ItemsSource = list

以上を実行した結果は図6のようになります。修正候補とWebサイトの検索結果が異なる表示になっています。

図6 複数種類のデータの表示
図6 複数種類のデータの表示

もちろん、WebResultやSpellResultクラスのテンプレートだけでなく、同様にNewsResultやImageResult、VideoResultクラスのテンプレートも用意すれば、それぞれの結果に応じた表示が可能です。ただし、Bing APIでは取得した結果の並び替えや、結果に別の内容を混在させることに利用制限がありますので、結果をまとめて表示する場合は注意してください。また、Silverlight 5 Betaは実稼働のサービスとして利用できるGo-Liveライセンスではありません。公開する場合は、開発者向けのサンプルに留めておきましょう。

おわりに

今回は以上です。いかがでしたでしょうか。Bing APIに関しては、JavaScript(jQuery)とSilverlightでの利用を併せてある程度紹介してきました。Bing APIはほかの検索サービスと比べると利用制限が緩めですので、うまく活用してみてください。

おすすめ記事

記事・ニュース一覧