
Recently I started working on a project that requires information about movies, music, books. To do this, you need to fill the database from another resource. Decided to use the free database Freebase.
Freebase is a large knowledge base containing structured data collected from many different sources. At the moment it has about 23 million topics. Each topic is associated with one or several types (people, places, films).
There are several options for getting data from Freebase:
- Download dump database (this can be done here )
- Use API
Permanent recovery from the dump dropped immediately (I want something more automated). Began to understand further. To work with the API, you must use one of 6 services:
- Search Service - search for entities by keyword;
- Mql Read Service - extraction of detailed data about entities;
- Topic Service - extract all the information about the entity;
- RDF Service - extraction of all information about an entity in RDF format;
- Text Service - extracting a short description for an entity;
- Image Service - getting pictures for the entity.
The first task that I had to do was autocomplete using Freebase and then writing to my database. Two services are suitable for this purpose: Search Service and Mql Read Service. I chose the second one because with it you can not only find but also get additional information. Immediately googled for ready-made lib (I do not like writing bikes). All that managed to find
freebase-dotnet (uses the old API) and
google-api-dotnet-client . Both do not implement asynchronous C # features.
Therefore, I had to write my lib, which can be found
here . It is still in beta version, but in the course of the current project I am finalizing it and making it stable, as it will be used in production.
')
Writing in nuget search Freebase4net, install the finished package.
To use the API, we need to get the key from
Google (metaweb was purchased by Google). The number of possible requests is limited to 100k requests per day.
To install ApiKey we can do so
FreebaseServices.SetApiKey("YOUR API KEY");
either so
<add key="FreebaseApiKey" value="AIzaSyC9N5HdZl15OjRcuOFxZ1SwngjCxIebbYM" />
Next, create the necessary service:
MqlReadService readService = FreebaseServices.CreateMqlReadService();
To search by entity name, send the following MQL query that uses regex:
[{
"type":"/music/artist",
"name":null,
"name~=":"^The Sco*$"
}]
This is done very simply using dynamic:
dynamic films = new ExpandoObject(); films.type = "/film/film"; films.name = FreebaseHelpers.Operators.CreateLikeOperator("^The Sco*$");
Now we actually make a request and get the data. Synchronously
MqlReadServiceResponse result = _readService.Read(films);
or asynchronously
MqlReadServiceResponse result = await _readService.ReadAsync(films);
Under the hood, the new HttpClient and its asynchronous capabilities are used.
Next we get the name of the entity
var name = result.Results[0].name;
Results - the dynamic array. Since the answer depends on the request, that is dynamic.
PS There is already ready
autocomplete , which has a rather attractive appearance and functionality. But I had to make my logic for caching data into my database.
With autocomplete sorted out, we go further. Next on the movie page I need to display a description and a picture. You can use Topic Service to do this, but its response structure is rather complicated - you need to figure out where to get the necessary information. For simplicity, TextService and ImageService were created. Therefore, I decided to use them.
string id = "/en/the_animal"; var textService = FreebaseServices.CreateTextService(); var response = await textService.ReadAsync(id); string description = response.Result;
Getting a link to a picture:
string id = "/en/the_animal"; var imageService = FreebaseServices.CreateImageService(); string image = imageService.GetImageUrl(id, maxwidth: "150");
If you need to make several requests, the functionality is asynchronously implemented.
dynamic thescorpions = new ExpandoObject(); thescorpions.name = "The Scorpions"; thescorpions.type = "/music/artist"; dynamic thepolice = new ExpandoObject(); thepolice.name = "The Police"; thepolice.type = "/music/artist"; List<MqlReadServiceResponse> multiFreebaseResponse = readService.ReadMultipleAsyncWithWait(thescorpions, thepolice);
If you have any ideas how this could be done better, I will be glad to hear them.