Click here to Skip to main content
15,886,362 members
Articles / Programming Languages / Typescript
Tip/Trick

A Typescript Library for Google Knowledge Graph (Freebase)

Rate me:
Please Sign up or sign in to vote.
0.00/5 (No votes)
16 Mar 2017MIT2 min read 10.9K   32   2  
I developed a Typescript library that wraps the Freebase API and expose some services. The library contains some definitions to provide type checking at compile time and intellisense. I also published the resulting JavaScript. The project is available under MIT license (open source).

Introduction

Have you ever seen a little box that eventually appears (depends on the query) as part of Google's search results? Type "Paris" and see the magic in action. The structured content that is displayed is part of the Google Knowledge Graph, a structured database that enhances the search engine.

Image 1

Google Knowledge Graph

Google Knowledge Graph is a huge database that contains structured data about almost everything. The intention is to enhance the search results with content that includes structured details of a particular topic. You can read more about Google Knowledge Graph at the official blog and Wikipedia.

We know that keywords are the components that form the basis of SEO, but what might have caught your attention is that the Knowledge Graph seems to be very well structured, in a way that could not have been built from search terms entered by users. In fact, the knowledge base is supported by Freebase, an open database developed by Metaweb. This company was acquired by Google in 2010.

Freebase is a massive knowledge base. It is structured, searchable, editable and open-licensed (free for commercial and non-commercial use under Creative Commons). It is an ambitious initiative to create a base of semantic data on virtually everything. It is collaborative and was built with the information of many sources, including individual contribution of the online community.

The Knowledge Graph is Open, Powerful and Google Provides an API for Remote Access

API documentation can be found on Google Developers. If you want direct access to the database, a data dump is available for download here. As we can see, this knowledge base creates endless possibilities for new promising applications.

Some important services:

  • search – useful for recommendation or displaying auto-complete results
  • topic – useful for displaying a structured article about a specific subject

You can play with these services using a web interface, here and here.

A Typescript Library for Google Knowledge Graph (Freebase)

I developed a Typescript library that wraps the Freebase API and expose some services. The library contains some definitions to provide type checking at compile time and intellisense. I also published the resulting JavaScript. The project is available under MIT license (open source) and is available for download on Github.

Image 2

Image 3

I hope it is useful for someone. ;)

C#
//The MIT License(MIT)

//Copyright(c) 2013 Minduca

//Permission is hereby granted, free of charge, to any person obtaining a copy
//of this software and associated documentation files(the "Software"), to deal
//in the Software without restriction, including without limitation the rights
//to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
//copies of the Software, and to permit persons to whom the Software is
//furnished to do so, subject to the following conditions:

//The above copyright notice and this permission notice shall be included in all
//copies or substantial portions of the Software.

//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
//SOFTWARE.

module Minduca.Freebase {

   export class FreebaseService {

      constructor(private auth?: IFreebaseRequestAuthenticationOptions) { }

      public topic(mId: string, 
      invokeOptions: IFreebaseTopicInvokeOptions, options?: IFreebaseTopicRequestOptions): any {
         if (!mId || mId == '')
            return;

         var url: string = this.getTopicUrl(mId, options);
         this.invoke(url, invokeOptions);
      }
      public search(options: IFreebaseSearchRequestOptions, 
          invokeOptions: IFreebaseSearchInvokeOptions): any {

         if (!options || !options.query || options.query == '')
            return;

         var url: string = this.getSearchUrl(options);
         this.invoke(url, invokeOptions);
      }
      public image(mid: string, options?: IFreebaseImageRequestOptions): string {
         return this.getImageUrl(mid, options);
      }

      private invoke(url: string, options: IFreebaseInvokeOptions): void {
         if (!options || !options.done)
            return;

         if (options.async == undefined)
            options.async = false;

         var request: JQueryAjaxSettings =
            {
               async: options.async,
               url: url,
               dataType: "json",
            };

         $.ajax(request)
            .done(options.done)
            .fail(options.fail)
            .always(options.always);
      }

      public static languageIsSupported(lang: string): boolean 
      { return FreebaseService.getSupportedLanguages().indexOf(lang) != -1; }

      private static getSupportedLanguages(): string[] 
      { return ['en', 'es', 'fr', 'de', 'it', 'pt', 'zh', 'ja', 'ko']; } //For more information, 
      //visit https://developers.google.com/freebase/v1/search-cookbook#language-constraints
      private getSearchUrl(options: IFreebaseSearchRequestOptions): string 
      { return this.buildServiceRequestUrl('search', options); }
      private getTopicUrl(mId: string, options?: IFreebaseTopicRequestOptions) 
      { return this.buildServiceRequestUrl('topic', options, mId); }
      private getImageUrl(mid: string, options?: IFreebaseImageRequestOptions): string 
      { return this.buildServiceRequestUrl('image', options, mid); }
      private getBaseUrl(): string { return 'https://www.googleapis.com/freebase/v1/'; }

      private buildServiceRequestUrl(serviceRelativePath: string, 
      jsonQS?: IFreebaseRequestOptionsBase, ...pathsVariables: string[]): string {

         var paths: string = '';
         var qs: string = '';

         if (this.auth && (this.auth.key || this.auth.oauth_token)) {
            if (!jsonQS)
               jsonQS = this.auth;
            else if (!jsonQS.key && this.auth.key)
               jsonQS.key = this.auth.key;
            else if (!jsonQS.oauth_token && this.auth.oauth_token)
               jsonQS.oauth_token = this.auth.oauth_token;
         }

         if (jsonQS)
            qs += '?' + $.param(jsonQS);

         if (pathsVariables && pathsVariables.length > 0) {
            paths = pathsVariables.join("/");
            if ((<any>paths.match("^/")) != "/")
               paths = "/" + paths;
         }

         return this.getBaseUrl().concat(serviceRelativePath, paths, qs);
      }
   }

   export interface IFreebaseRequestAuthenticationOptions {
      key?: string;
      oauth_token?: string;
   }

   export interface IFreebaseRequestOptionsBase extends IFreebaseRequestAuthenticationOptions {
      prettyPrint?: boolean;
      quotaUser?: string;
      userIp?: string;
   }

   //For more information, visit https://developers.google.com/freebase/v1/search
   export interface IFreebaseSearchRequestOptions extends IFreebaseRequestOptionsBase {
      as_of_time?: string;
      callback?: string;
      cursor?: number;
      domain?: string;
      encode?: string;
      exact?: boolean;
      filter?: string;
      format?: string;
      indent?: boolean;
      lang?: string;
      limit?: number;
      mql_output?: string;
      prefixed?: boolean;
      query: string;
      scoring?: string;
      spell?: string;
      stemmed?: boolean;
      type?: string;
      with?: string;
      without?: string;
      ///
      output?: string; //For more information, 
      //visit https://developers.google.com/freebase/v1/search-output
   }

   //For more information, 
   //visit https://developers.google.com/freebase/v1/
   //topic-response#references-to-image-objects 
   // and https://google-api-python-client.googlecode.com/
   //hg-history/29446c82e297ecb8ca7dd024698b973dab51437f/docs/dyn/freebase_v1.html
   export interface IFreebaseImageRequestOptions extends IFreebaseRequestOptionsBase {
      maxwidth?: number;
      maxheight?: number;
      fallbackid?: string;
      pad?: boolean;
      mode?: string;
   }

   //For more information, visit https://developers.google.com/freebase/v1/topic
   export interface IFreebaseTopicRequestOptions extends IFreebaseRequestOptionsBase {
      dateline?: string;
      filter?: string;
      lang?: string;
      limit?: number;
      raw?: boolean;
   }

   export interface IFreebaseSearchInvokeOptions extends IFreebaseInvokeOptions {
      done(data: IFreebaseSearchResult, textStatus: string, jqXHR: JQueryXHR): any;
   }
   export interface IFreebaseTopicInvokeOptions extends IFreebaseInvokeOptions {
      done(data: IFreebaseTopicResultProperty, textStatus: string, jqXHR: JQueryXHR): any;
   }

   export interface IFreebaseInvokeOptions {
      done(data: any, textStatus: string, jqXHR: JQueryXHR): any;
      fail? (jqXHR: JQueryXHR, textStatus: string, errorThrow: string): any;
      always? (jqXHR: JQueryXHR, textStatus: string): any;
      async?: boolean;
   }

   export interface IFreebaseSearchResult {
      status: string;
      correction?: string[];
      result: IFreebaseSearchResultItem[];
      cursor: number;
      cost: number;
      hits: number;
   }

   export interface IFreebaseSearchResultItem {
      mid: string;
      id: string;
      name: string;
      notable: {
         name: string;
         id: string;
      };
      lang: string;
      score: string;
      output?: { [prop: string]: any };
   }

   export interface IFreebaseResultError {
      error:
      {
         errors: {
            domain: string;
            reason: string;
            message: string;
            location?: string;
            locationtype?: string;
         }[];
         code: string;
         message: string;
      }
   }

   export interface IFreebaseTopicResultProperty {
      id: string;
      property: { [prop: string]: IFreebaseTopicResultPropertyDescription };
   }
   export interface IFreebaseTopicResultPropertyDescription {
      valuetype: string;
      values: IFreebaseTopicResultPropertyValueBase[];
      count: number;
   }
   export interface IFreebaseTopicResultPropertyValueBase extends IFreebaseTopicResultProperty {
      text: string;
      lang: string;
      creator: string;
      timestamp: string;
   }

   export interface IFreebaseCitation {
      provider: string;
      statement: string;
      uri: string;
   }
}  

License

This article, along with any associated source code and files, is licensed under The MIT License


Written By
Software Developer
Canada Canada
Software architect, Machine learning engineer, full stack cloud developer, MSc in Machine Learning, Microsoft Certified Solutions Developer (MCSD).

Comments and Discussions

 
-- There are no messages in this forum --