Login

Factual Blog /

Crosswalk the Web with Java and Factual

Factual is pleased to announce the release of a new Java driver for our API. The driver supports Factual’s API features, including Crosswalk, Resolve, and geo location functionality around the Factual Places API.

We put a priority on making this driver easy to use. It lets you focus on building your Factual queries and using the results in Java. It handles details like OAuth, url encoding, and JSON marshaling so you don’t have to.

The driver is hosted on Maven Central, so if you’re using Maven you can install it in your project just by adding this to your pom file:

<dependency>
  <groupId>com.factual</groupId>
  <artifactId>factual-java-driver</artifactId>
  <version>1.0</version>
</dependency>

Once you have the driver installed in your Java project, here’s how you create an authenticated handle to Factual:

Factual factual = new Factual("YOUR_API_KEY", "YOUR_API_SECRET");

The driver provides a fluent interface to build your Factual queries. For example, here’s how you build a query to use full text search and a geo filter to find cafes within 5,000 meters of your location, using your latitude and longitude:

Query q = new Query()
  .search("cafe")
  .within(new Circle(34.06018, -118.41835, 5000));

There’s also fluent support for detailed results filtering. To illustrate a bit of this, here’s how you build a query to return the name and address of cafes within 5,000 meters of a lat/long, while limiting to a specific zip code, category, and size of returned results:

Query q = new Query()
  .only("name", "address")
  .search("cafe")
  .within(new Circle(34.06018, -118.41835, 5000))
  .field("postcode").equal("90067")
  .field("category").equal("Food & Beverage")
  .limit(25);

We’re also experimenting with built-in support for the venerable Data Science Toolkit. This gives you an easy way to lookup location coordinates based on address information. For example, you could find Factual’s latitude and longitude by using the text “1801 avenue of the stars, century city, ca”:

Coord coord = new DataScienceToolkit()
  .streetToCoord("1801 avenue of the stars, century city, ca");

This support is built in to the driver’s fluid interface for querying on Factual’s Places data. Here’s an example of finding cigar shops within 5,000 meters of an address:

ReadResponse cigars = factual.fetch("places", new Query()
  .search("cigars")
  .near("1801 avenue of the stars, century city, ca", 5000));

Crosswalk The Web

The driver has full support for Crosswalk, which makes it super easy for you to translate how Place entities are represented by 3rd party APIs and websites.

To illustrate, let’s take a look at the first record returned from our cigar search:

System.out.println(cigars.getJson());

That looks like:

{
  "version" : 3,
  "status"  : "ok",
  "response":
  {
    "data":
    [{
       "factual_id": "5e2c36e4-aeb8-49b8-8652-defcd8ad5808",
       "name"      : "Buena Vista Cigar Club",
       "address"   : "9715 Santa Monica Blvd",
       "locality"  : "Beverly Hills",
       "region"    : "CA",
       "country"   : "US",
       "postcode"  : "90210",
       "tel"       : "(310) 273-8100",
       "category"  : "Shopping > Tobacco Shops",
       "website"   : "http://www.buenavistacigarclub.com/",
       "latitude"  : 34.068735,
       "longitude" : -118.407808,
       "status"    : "1",
       "$distance" : 1280.624
     },
     ...

That’s some tasty data about the Buena Vista Cigar Club, including its unique Factual ID. Next, by using Crosswalk and the Factual ID, we can get links out to other authorities for this entity:

CrosswalkResponse crosswalks = factual.fetch("places",
  new CrosswalkQuery().factualId("5e2c36e4-aeb8-49b8-8652-defcd8ad5808"));

System.out.println(crosswalks.getJson());

That’s going to look like:

{
  "version" : 3,
  "status"  : "ok",
  "response":
  {
    "data":
    [
      {
        "factual_id"  : "5e2c36e4-aeb8-49b8-8652-defcd8ad5808",
        "namespace"   : "facebook",
        "namespace_id": "141751493637",
        "url"         : "http://www.facebook.com/pages/Buena-Vista-Cigar-Club/141751493637"
      },
      {
        "factual_id"  : "5e2c36e4-aeb8-49b8-8652-defcd8ad5808",
        "namespace"   : "yelp",
        "namespace_id": "",
        "url"         : "http://www.yelp.com/biz/buena-vista-cigar-club-beverly-hills"
      },
      {
        "factual_id"  : "5e2c36e4-aeb8-49b8-8652-defcd8ad5808",
        "namespace"   : "yellowpages",
        "namespace_id": "",
        "url"         : "http://www.yellowpages.com/beverly-hills-ca/mip/buena-vista-cigar-club-12303827"
      },
      ...

Each record represents a specific Crosswalk authority, or what we call a “namespace”, e.g. “yelp”, “facebook”, “yellowpages”, and so on.

Attributes include the namespace’s link and ID for the entity. E.g., the Yelp link for the Buena Vista Cigar Club is http://www.yelp.com/biz/buena-vista-cigar-club-beverly-hills, and the Yelp ID is “u_3ywlxdwq–WxxOO_3TVg”.

Crosswalk lets you go the other direction as well. Say all you have is the Facebook ID for the Buena Vista Cigar Club. You can do this…

System.out.println(
  factual.fetch("places", new CrosswalkQuery()
    .namespace("facebook")
    .namespaceId("141751493637")
    .only("facebook")
  ).getJson());

That looks like…

{
  "version" : 3,
  "status"  : "ok",
  "response":
  {
    "data":
    [
      {
        "factual_id"  : "5e2c36e4-aeb8-49b8-8652-defcd8ad5808",
        "namespace"   : "facebook",
        "namespace_id": "141751493637",
        "url"         : "http://www.facebook.com/pages/Buena-Vista-Cigar-Club/141751493637"}
    ],
    "included_rows"  : 1,
    "total_row_count": 1
  }
}

… which includes the Factual ID of the entity. With that you can continue querying Factual’s system for whatever you want to know about the entity.

Factual has support for 30+ namespaces. You can see the detailed list here.

You can use Crosswalk to relate and aggregate content across web authorities, and mashup the best content from each.

Resolve

Resolve lets you start with incomplete data you may have for an entity, and get out the full entity data, assuming Factual is able to make a high confidence match.

For example, say you know the name of a place and some imprecise location. The Java driver lets you use Resolve to get a single, high-quality match, like this:

System.out.println(
  factual.resolve(
    new ResolveQuery()
      .add("name", "Buena Vista")
      .add("latitude", 34.06)
      .add("longitude", -118.40)

This shows you Factual’s full record for the resolved entity as a Map, including its Factual ID:

{
  name      = Buena Vista Cigar Club,
  region    = CA,
  status    = 1,
  tel       = (310) 273-8100,
  postcode  = 90210,
  country   = US,
  category  = Shopping > Tobacco Shops,
  resolved  = false,
  address   = 9715 Santa Monica Blvd,
  locality  = Beverly Hills,
  longitude = -118.407808,
  latitude  = 34.068735,
  similarity= 0.7142857142857143,
  factual_id= 5e2c36e4-aeb8-49b8-8652-defcd8ad5808
}

Conclusion

We hope you’ll find new and interesting uses for Factual, including Crosswalk and Resolve. If you end up releasing something interesting, please let us know so we can give you a shout-out!

Complete docs on how to install and use the Java driver are here. The driver itself is open source. The test suite includes integration tests as well as simple demos to illustrate usage. If you have any questions or suggestions, we hope you’ll contact us through the driver’s github project.

Factual’s service is currently in Beta, and you can obtain an API key here.

P.S.: You should follow me on Twitter here.