BLinq - Linq to Bing Search APIs

This post introduces a small sample I'm calling BLinq, which allows you to use LINQ to search for pages and images using the Bing search API... as a first step leading up to some .NET RIA Services integration.

As part of validating and playing with some of the extensibility features in .NET RIA Services, I needed to write a LINQ provider. This was also a good opportunity to delve into some of the deeper technical aspects of the IQueryable construct, expression trees and related concepts, which I had not gotten into first-hand until now. For my prototyping, I decided to write a LINQ provider for querying Bing to search for pages and images. This post will focus on using the LINQ provider itself, and seeing it in action, and in my next post I'll tie it all back to .NET RIA Services. I am calling this BLinq. :-)

Bing has a new search API that provides you the option of using REST interface (XML or JSON) or a SOAP interface. My LINQ provider provides a more natural LINQ syntax that you can now use without having to worry about protocol details, web requests, URIs etc. Under the covers the LINQ functionality builds on the REST/XML API.

Here is an example of a basic search for pages using BLinq:

BingContext bing = new BingContext(appKey);
IQueryable<PageSearchResult> pagesQuery =
    from p in bing.Pages
    where p.Query == "nikhil"
    select p;

foreach (PageSearchResult page in pagesQuery) {
    // Write out page members (title, uri, description, display URL and date)
}

Simple enough? BingContext is very much like a Linq-to-SQL DataContext. It has a Pages property of type IQueryable<PageSearchResult> (ala a Table<T> in a DataContext). Of course this is LINQ, and so you can use standard LINQ constructs like Skip and Take for example to page over the search results. For example:

// Get the first search result...
pagesQuery = pagesQuery.Take(1);

BLinq provides a fluent interface to configure one or more additional options when invoking a search request. For example, say I want to search for pizza in Redmond:

IQueryable<PageSearchResult> pagesQuery =
    from p in bing.Pages.LocalResults("Redmond")
    where p.Query == "pizza"
    select p;

Other options include scoping results to a particular site. For example, I want to search for Silverlight-related content on my site:

IQueryable<PageSearchResult> pagesQuery =
    from p in bing.Pages.ScopeResults("nikhilk.net")
    where p.Query == "silverlight"
    select p;

So far I've been showing examples that search for pages. BLinq also supports searching for images. For example, say I want to search for images of Yellowstone, and turn on the strict filter (another example of an option I can specify on the query):

IQueryable<ImageSearchResult> imagesQuery =
    from img in bing.Images.SafeResults()
    where img.Query == "Yellowstone"
    select img;
var imagesPage1 = imagesQuery.Take(10).ToList();
var imagesPage2 = imagesQuery.Skip(10).Take(10).ToList();

foreach (ImageSearchResult img in imagesPage1.Union(imagesPage2)) {
    // Write out image title, image URI, image size, containing page URI,
    // thumbnail URI, and thumbnail size.
}

Generally speaking, BLinq works like any other LINQ provider for the set of capabilities provided by the underlying API (where clause on the Query member, Skip and Take). As a result, not only does the code look consistent with other LINQ code, but standard tools for LINQ just work (as well as higher level frameworks). Here is a screenshot of experimenting with BLinq in the LINQPad tool.

BLinq in LINQPad

The Implementation
LINQ ProgrammingLINQ in ActionUnder the covers, BLinq contains an implementation of IQueryable that is backed by a Bing-based implementation of IQueryProvider. This query provider is responsible for walking the LINQ expression trees created by the app developer and turning the expression tree into a corresponding URI suitable for use with the Bing API. When asked to execute the expression, the query provider uses that URI to issue a web request, and materialize search results from the resulting response XML. If you're interested in understanding the basics of writing such a LINQ provider, you might find BLinq an interesting sample to study, as is is both self-contained without lots of dependencies, and a small enough implementation to understand it all the way through. I've kept this post focused on using BLinq... if you have questions on the implementation, feel free to post in the comments. You can also check out LINQ Programming or LINQ in Action, which go deeper into concepts like LINQ expressions, lambdas, and building your own LINQ provider above and beyond using LINQ.

Next Steps
This is just a start. It would be interesting to fully flesh out BLinq to enable searching for spellings, related searches, ads etc. to cover the full capabilities of the underlying Bing API. Perhaps the folks from the Bing team would be interested in getting this functionality into the Bing SDK. Also, as mentioned above stay tuned for the next post, where I'll show how this can be integrated with .NET RIA Services on the server and client, as .NET RIA Services also builds on the same LINQ building blocks.

You can download the sample framework, which implements the LINQ functionality, and the sample code. Note that you'll also need to get an API key by registering for using the service if you'd like to compile and run the code associated with this post on your end.


[ Tags: | | ]
Posted on Saturday, 8/22/2009 @ 10:35 AM | #Projects


Comments

13 comments have been posted.

Joe Mayo

Posted on 8/22/2009 @ 8:12 PM
Nice one - Bing search really calls out for a LINQ provider. Looking forward to your RIA Services post that incorporates it.

Joe

Michael Washington

Posted on 8/23/2009 @ 9:12 AM
This is an example of a great "you can get the point of this in about 10 seconds". The code is simple and the uses are endless. It is also another example of why Linq is one of the greatest things to ever come out of Redmond (in addition to Silverlight of course :))

sayitfast

Posted on 8/23/2009 @ 3:18 PM
When I first noticed this article I was thinking it was part of this blinq. http://www.asp.net/Downloads/sandbox/blinq/

This is very kewl though!!!

Vijay Santhanam

Posted on 8/23/2009 @ 7:20 PM
Rad! This is a use of Bing that definitely one-ups google. I've wanted something like this to integrate into my apps for a long time.

steve potter

Posted on 8/23/2009 @ 8:09 PM
Dude you're a mad scientist. Great work. Not to be a pest, but if script# is dead as it appears, it would be cool to announce it. Who would win in a programming fight - you or Scott Guthrie?

rtpHarry

Posted on 8/24/2009 @ 2:11 AM
I think the project is dead now but there is already a Microsoft technology called blinq:

http://forums.asp.net/1076.aspx
"Blinq is a tool for generating ASP.NET websites for displaying, creating, and manipulating data based on database schema. You can provide feedback and ask questions about the Blinq preview in this forum."

rob

Posted on 8/24/2009 @ 2:10 PM

vikram

Posted on 8/24/2009 @ 6:58 PM
The name would certainly confuse with the earlier BLinq prototype

Milan Negovan

Posted on 8/24/2009 @ 7:30 PM
How about the name "Binq" to disambiguate from the now--defunct Blinq. :)

I will definitely try your Bing provider. I've used MSN Search web services for years and, honestly, they sucked. Hope Bing will do better!

eric

Posted on 8/24/2009 @ 10:04 PM
blinq?
so cool~~ thanks for share

arlen navasartian

Posted on 8/25/2009 @ 4:05 AM
Hello ,
How can i define
BingContext bing = new BingContext(appKey);

BingContext is undefined in C# 2008

Nikhil Kothari

Posted on 8/25/2009 @ 9:51 AM
Clearly the name caused some confusion, and probably brought back some memories of the older project. I didn't expect that. Anyway, I thought it was an interesting name... call it LINQ to Bing if it helps.

@arlen - did you reference the BLinq assembly and add a reference to the BLinq namespace?

Vb Guest

Posted on 9/19/2009 @ 4:51 AM
Linq is really good. This is what i expected when bing has been released. the integration of search is going to be integral part of web development(especially asp.net).
Post your comment and continue the discussion.