Search
From Freebase
Contents |
In the Freebase client
Main article: Freebase client
You can search for information on Freebase the same way you would on any website, by entering a term in the Search box and clicking Search. If you're on a bases page, you can search only within that base, or you can click the arrow next to Search to select a Freebase-wide search. In addition, our autocomplete feature can help you go directly to the topic you're looking for without needing to read through a list of search results.
Let's say you're searching for the comic The Dark Knight to see what year it was published. As you start to type Dark Knight into the search box, autocomplete will begin suggesting matches. When you've typed in the full name, you'll see a list of Dark Knight topics in Freebase. Beneath each topic name you'll see the information category, or type, it's associated with; there's a Dark Knight film, tv episode, and musical track, among others. If you move your cursor over any of those topic names, you'll also see a brief excerpt from the topic description. From this you can learn that the full title of The Dark Knight comic is Batman: The Dark Knight Returns.
If one of the autocomplete suggestions is the topic you're looking for, just move your cursor over it to highlight it in blue, then click. If you want to search all of Freebase instead, finish entering your search terms, click Search (NO LONGER THERE, SO HIT ENTER KEY), and you'll get a list of the first 30 topics matching your search term. You can then narrow your results further by entering a type in the Type box on the search results page.
A couple tricks for using search and autocomplete:
- If you already know the type for the topic you want, you can enter that as well, in this format:
search term type:/domain/type
Example:
Dark Knight type:/film/film
will only show you Dark Knight topics typed as film).
- You can also use Views to query for topics and filter them according to various criteria.
Search service (Relevance) only has knowledge of data in Freebase; it doesn't have the benefit of the entire web space as do commercial web search engines. It wouldn't know to return topic /en/the_edge when someone searches for "David Howell Evans" if that data (modeled in Freebase as an Alias) didn't exist. Product requirements and previous user requests have mandated that topic name and alias be weighted with regard to Relevance more than anything else. To boost the rank of a desired result, aliases can and should be added to a topic.
The search box at Freebase.com uses a suggest service that in turn utilizes the public /api/service/search, to satisfy the web app's unique business logic that most likely would not apply or even make sense to general user searches. For example, private suggest blocks Freebase system types from being included in the search results. As for the role played by relevance search, the most common use case is lookup by "name/alias + type". For queries where you need the complete set of topics satisfying a requirement, such as having a certain value in a specific property, MQL is the right tool, not Search service.
Via the API
If you are a developer, you can search Freebase topics using the search function in the Freebase API.
- Freebase API - New API using Google APIs
- Official Search API documentation - Old Freebase API Search
FAQs
- Why are newly created topics not showing up via the search service?
The search results are not updated in real-time, but via a background process which looks for changes to the graph and updates the search results accordingly. This process usually manages to bring the search results up to date with the graph in a minute or so, but if the system is under heavy load and/or backlogged due to a large data load, then it can be longer.
The Metaweb Search Service
This article contains content originally taken from the MQL Manual, which is no longer maintained. It may need cleanup to make sense as a standalone document. Please go ahead and help us do this!
The freebase.com website includes a search text box in the upper-right corner. Type in some text and hit return, and freebase will list database entries that match your query. While you type it offers a drop-down menu of suggestions (or auto-completions). Both the search function and the auto-complete function are powered by Metaweb's search service. For every object in the database, the search service indexes the name and aliases (/common/topic/alias) of the object, as well as any other properties of /type/text, and any documents associated (such as through /common/topic/article) with the object. Search results are ordered according to an opaque, but well-tuned ranking system to yield the most relevant results first. At the time of this writing <footnote><para>September, 2008</footnote>
Metaweb's search engine is not
language-aware, and indexes all text without regard to its source
language.
</para>
This section describes the search API so that you can use it in your own web applications. Note, however that if you simply want to duplicate on your own website the searching and drop-down suggestion functionality of freebase.com, you should consider using the open-source freebase-suggest library, which is available at http://code.google.com/p/freebase-suggest/.
Keep in mind that the search service is a sophisticated full-text search engine that indexes Metaweb objects and the documents associated with them. Many simpler searches (such as looking for objects with particular words in their names) are best expressed as MQL queries (using the ~= operator for pattern matching) using the mqlread service.
The search service is a web-based service, like mqlread. The base URL for requesting search results from freebase.com is:
http://api.freebase.com/api/service/search
Unlike mqlread, the search service does not encode queries as JSON objects, and instead passes the query text and other search variables as URL parameters. For example, to search for people named "Smith", you could use this URL:
http://api.freebase.com/api/service/search?query=Smith&type=/people/person
The URL parameters to search are described in <xref linkend="searchinput"/>. If you enter the above URL into a browser, you'll see that the search service, like mqlread, returns its results as a JSON object. The format of the results are covered in <xref linkend="searchoutput"/>.
The sub-sections that follow describe the input and output of the search service and then demonstrate its use with a JavaScript example.
Search Input
Input to the search service takes the form of HTML form-encoded parameters appended to the URL. There are four categories of parameters:
<itemizedlist>
- parameters that specify the text to be matched;
- parameters that narrow the field of search by domain or type;
- parameters that specify the number or offset of the desired results; and
- parameters that affect the format of the returned results.
</itemizedlist>
Every invocation of the search service must include either a query parameter or a prefix parameter (but not both). Both specify text to be searched for. If you use the query parameter, your text will only match complete words. If you specify prefix, however, any word that begins with your text matches. Searches are case-insensitive and ignore punctuation and accents on characters. The search target you specify may include multiple words, but you may not include multiple query or prefix parameters in a search URL.
You can narrow the field of search (or at least change the way the search service ranks results) with the domain and type parameters. The value of the domain parameter should be the id of a Metaweb domain. For example:
http://api.freebase.com/api/service/search?query=Smith&domain=/film
This query looks for topics that match the word Smith and have at least one type in the /film domain. Results might include the /film/actor Will Smith, and the /film/film "Mr. Smith Goes to Washington".
It is unusual to do a domain constraint alone as in the example above. Here is an alternative (with the URL truncated to fit on one line) that looks for film-related people named Smith. It matches actors and producers, but not films:
/api/service/search?query=Smith&type=/people/person&domain=/film
The type parameter specifies the id of a Metaweb type. In the search URL above, it specifies that each of the matches should be a /people/person object.
A search URL may include more than one type parameter to specify more than one type. The way that type parameters affect search results is controlled by the type_strict parameter, which must have one of the following three values:
- all
- Search results will only include objects that are members of all of the types described.
- any
- Search results will only include objects that are members of at least one of the specified types. Objects that match more types will have increased relevance scores, and may appear earlier in the search results. This is the default type matching mode when no
type_strictparameter is given. - should
- The specified types will be used in computing the relevance of the search results, but results may include objects that do not match any of the specified types.
Here are some more search URLs (abbreviated so they fit on one line) with comments indicating what they do:
// Find objects matching "Smith" that are either films or actors.
// type_strict=any is implicit in this search
search?query=Smith&type=/film/film&type=/film/actor
// Find objects matching "Smith" that are both films and actors.
// Results, if any, probably represent typing errors in the database.
search?query=Smith&type=/film/film&type=/film/actor&type_strict=all
// Find objects matching "Smith"; give priority to films and actors
search?query=Smith&type=/film/film&type=/film/actor&type_strict=should
// Find objects matching "Carnivores" with stemmed search support and that are then filtered with mql_filter for only those that are still untyped. Stemmed support is useful for perform broader searches that have scientific names or terms
http://api.freebase.com/api/service/search?query=carnivores&stemmed=1&indent=1&mql_filter=[{%22type%22:{%22id%22:null,%22id!=%22:%22/common/topic%22,%22optional%22:%22forbidden%22}}]
By default, the search service returns the 20 most relevant results. You can request a different number of results with the limit parameter. If you want to retrieve another page of less-relevant results, you can use the start parameter:
search?query=Smith // Results 1-20 search?query=Smith&limit=10 // Results 1-10 search?query=Smith&start=10&limit=10 // Results 11-20
The final category of URL parameters are those miscellaneous parameters that affect the formatting of the results. Use escape=false to turn off HTML escaping of the &, <, and > characters in the results. Use indent=true if you want the JSON string of search results to be pretty-printed so that it is more human-readable. This parameter is useful when experimenting with search URLs in a web browser, but is not necessary when executing searches from scripts. The search results shown in the next section are pretty-printed, even though the indent parameter is omitted from the search URLs.
If you want to use the search service from client-side JavaScript code, you'll need to use the callback parameter. This parameter enables JSONP just as it does for mqlread: it wraps a JavaScript function invocation around the JSON result string. Using the search service with JavaScript is demonstrated in <xref linkend="metaweb2.js"/> and <xref linkend="albumlist2.html"/>.
Finally, the mql_output parameter specifies which properties of each matching object are to appear in the search results. See <xref linkend="searchoutput"/> for details and examples.
Search Output
The search service returns a JSON-encoded envelope object just as the mqlread service does. This object has a code property that specifies whether the search succeeded or failed. If this code is anything other than "/api/status/ok", then the search failed. In this case, the envelope object has a messages property whose value is an array of one or more message objects. The messages array returned by search is just like that returned by mqlread: each element of this array includes a code property that identifies the specific kind of error and a message property that can be used to generate a diagnostic message. Certain message code values also have an associated info property that provides error details, but the list of codes and the format of their associated info objects is not documented.
If you get an error from the search service, it typically means that you invoked it incorrectly. Errors can occur if (for example) you don't specify either the query or prefix parameter, or if you specify an illegal value for the type_strict parameter, or if you specify an undefined id as the value of the type or domain parameter. If a search URL is properly constructed, the search is considered a success, even if it matches nothing and returns no results.
If the code property of the envelope object is "/api/status/ok", then the query was a success, and the envelope has a result property that holds a (possibly empty) array of search results.
The following search URL, for example:
http://api.freebase.com/api/service/search?query=Smith&limit=1
might return these results:
{
"status": "200 OK",
"code": "/api/status/ok",
"transaction_id":"cache;cache01.p01.sjc1:8101;2008-09-16T21:47:14Z;0006",
"result": [
{
"id": "/guid/9202a8c04000641f80000000004f16a0",
"name": "William Smith",
"alias": [],
"type": [
{ "id": "/common/topic", "name": "Topic" },
{ "id": "/people/person", "name": "Person" },
{ "id": "/people/deceased_person", "name": "Deceased Person" }
],
"article": { "id": "/guid/9202a8c04000641f80000000004f16a5" },
"image": null
}
]
}
The envelope object includes status, code and transaction_id properties just mqlread response envelopes do. The interesting part of the envelope object is the result array. For this example query, we explicitly specified a limit of 1, so the array has only one element, but in general each element of the result array provides information about a single Metaweb object that matched the search query. By default (if you do not specify a mql_output parameter in the search query), each element is an object with the following properties:
- id
- The Metaweb id of the matched object.
- name
The name of the matched object. (At the time of this writing, <footnote><para>September, 2008</footnote> there is no way to specify the preferred language in which the name should be returned.) </para>
- alias
- An array of nicknames for the object. These are the values of the
/common/topic/aliasproperty. - type
- An array that specifies the types of the object. Each element of this array is an object with
idandnameproperties that specify the Metaweb id and the human-readable name of the type. - article
- If the matched object has at least one associated document as the value of the
/common/topic/articleproperty, then this result property refers to an object with a singleidproperty. Thisarticle.idproperty is the Metaweb id of the most recent document associated with the object. A blurb from this article can be a useful addition to search results. (<xref linkend="transservice"/> shows how to retrieve article blurbs.) If the matched object has no associated documents, then this property isnull. - image
- If the matched object has at least one associated image as the value of the
/common/topic/imageproperty, then this property refers to an object with nothing but anidproperty.image.idis a Metaweb id of the first image (the image withindex:0, see <xref linkend="orderedcollections"/>). It may be useful to include a thumbnail of this image in a listing of search results. (<xref linkend="transservice"/> shows how to retrieve image thumbnails.) If the matched object has no associated images, then thisimageproperty isnull.
These default properties of the elements of the results array can be overridden with the mql_output URL parameter. The value of this parameter should be a MQL query in square brackets. Such as:
http://api.freebase.com/api/service/search?query=Kim%20Kardashian&mql_output=[{%22id%22:null,%22name%22:null}]&indent=1
The search service adds the following properties to the query you specify:
"guid": null "guid|=": [guids of all matching objects here]
The guid|= property specifies the guids of all objects that matched the search. The query is passed to mqlread, and the results become the results array of the search. Consider this query (which wraps onto two lines), for example:
http://api.freebase.com/api/service/search?query=love&type=/music/track&limit=3
&mql_output=[{"name":null,"/music/track/artist":null}]
It returns results like these:
{
"status": "200 OK",
"code": "/api/status/ok",
"transaction_id":"cache;cache01.sandbox.sjc1:8101;2008-09-16T23:13:07Z;0001",
"result": [{
"guid" : "#9202a8c04000641f8000000001268f44",
"name" : "Tainted Love",
"/music/track/artist" : "Soft Cell"
},{
"guid" : "#9202a8c04000641f80000000012b0704",
"name" : "Endless Love",
"/music/track/artist" : "Diana Ross & Lionel Richie"
},{
"guid" : "#9202a8c04000641f800000000129a206",
"name" : "The Power of Love",
"/music/track/artist" : "Huey Lewis & the News"
}]
}
NOTE: mql_output is not allowed to filter, so you have to add a mql_filter parameter to your query, at times.
For example:
http://api.freebase.com/api/service/search?query=usa&type=/location/country&type=/location/dated_location&type_strict=all&mql_filter=[{%22key%22:[{%22namespace%22:%22/authority/iso/3166-1/alpha-2%22}]}]&mql_output=[{%22name%22:null,%22id%22:null,%20%22key%22:[{%22namespace%22:%22/authority/iso/3166-1/alpha-2%22,%20%22value%22:null}],%22/location/dated_location/date_dissolved%22:null,%22/common/topic/image%22:[{}]}]&indent=1
mql_filter takes care of eliminating matches that don't fit the namespace constraint and mql_output then formats the results of what's left over after the filtering.
The point of mql_filter is that, if results are lost due to the filter, the text search is re-run until enough results are found to pass the filter or there are no more results.
Example: Searching for Band Names
To demonstrate the search service, let's extend the metaweb.js module of <xref linkend="metaweb.js"/>. <xref linkend="metaweb2.js"/> defines a JavaScript function named Metaweb.search() that invokes the search service. The code in this example is intended as an extension of <xref linkend="metaweb.js"/>. It depends on the Metaweb object, Metaweb.HOST constant and Metaweb.makeCallbackName() function defined in that previous example.
metaweb.js: searching Metaweb
Metaweb.SEARCH = "/api/service/search"; // URL path to the search service
// Invoke the Metaweb search service for the specified query.
// Asynchronously pass the array of results to the specified callback function.
//
// The first argument can be a string for simple searches or an object
// for more complex searches. If it is a string, it should take the form
// [type:]text[*]
// That is: the text to be searched for, optionally prefixed by a type id
// and a colon and optionally suffixed with an asterisk. Specifying a type
// sets the type parameter for the search, and adding an asterisk makes it a
// prefix search.
//
// If query argument is an object, then its properties are translated into
// search parameters. In this case, the object must include either
// a property named query (for an exact match) or a property named prefix
// (for a prefix match). Other legal properties are the same as the
// allowed parameters for the search service: type, type_strict, domain,
// limit, start, and so on. To specify multiple types, set the
// type property to an array of type ids. To specify a single type, set
// the type property to a single id.
Metaweb.search = function(query, callback) {
var q = {}; // The query object
if (typeof query == "string") {
// If the query argument is a string, we must convert it to an object.
// First, see if there is a type prefix
var colon = query.indexOf(':');
if (colon != -1) {
q.type = query.substring(0, colon);
query = query.substring(colon + 1);
}
// Next see if there is an asterisk suffix
if (query.charAt(query.length-1) == '*') // prefix match
q.prefix = query.substring(0, query.length-1);
else
q.query = query;
}
else {
// Otherwise, assume the query argument is an object and
// copy its properties into the q object.
for(var p in query) q[p] = query[p];
}
// With mqlread, we would JSON-encode the query object q. For the search
// service, we convert the properties of q to an array of URL parameters
var parameters = [];
for(var name in q) {
var value = q[name];
if (typeof value != "object") { // A single value for the parameter
var param = name + "=" + encodeURIComponent(value.toString());
parameters.push(param);
}
else { // Otherwise, there is an array of values: multiple types
for(var index in value) {
var elt = value[index];
var param = name + "=" + encodeURIComponent(elt.toString());
parameters.push(param);
}
}
}
// Now convert the array of parameters into a URL
var url = Metaweb.HOST + Metaweb.SEARCH + "?" + parameters.join('&');
// Generate a name for the function that will receive the results
var cb = Metaweb.makeCallbackName(url);
// Add the JSONP callback parameter to the url
url += "&callback=Metaweb." + cb;
// Create the script tag that will fetch that URL
var script = document.createElement("script");
// Define the function that handles the results from that URL
Metaweb[cb] = function(envelope) {
// Clean up by erasing this function and deleting the script tag
document.body.removeChild(script);
delete Metaweb[cb];
// If the query was successful, pass results to the callback
// Otherwise, throw an error message
if (envelope.code == "/api/status/ok")
callback(envelope.result);
else {
throw "Metaweb.search: " + envelope.messages[0].code +
": " + envelope.messages[0].message;
}
}
// Now set the URL of the script tag and add that tag to the document.
// This triggers the HTTP request and submits the search query.
script.src = url
document.body.appendChild(script);
};
<xref linkend="albumlist2.html"/> demonstrates how this Metaweb.search() function might be used in practice. It is a new version of the JavaScript-based album listing application shown in <xref linkend="albumlist.html"/>. The relevant new feature of this version is that if the user enters a name that is not a known band name, the application uses that name a in a search query and lists the results. For brevity, the album-listing features of this new version have been simplified, and the track-listing features have been removed.
albumlist2.html: Searching for bands
<html>
<head>
<script src="json2.js"></script> <!-- Defines JSON.stringify() -->
<script src="metaweb.js"></script> <!-- Defines Metaweb.read() -->
<script>
/* Display albums by the specified band */
function listAlbums(band) {
// Find the document elements we need to insert content into
var title = document.getElementById("title");
var albumlist = document.getElementById("albumlist");
var query = [{ // This is our simple MQL query
type: "/music/artist", // Find a band
name: band, // With the specified name
album: [] // And return all album names
}];
// Issue the query and invoke the function below when it is done
Metaweb.read(query, function(result) {
// If no result, the band was unknown, so search for matches
if (!result || result.length == 0) searchForBands(band);
// Otherwise, we found a band, so list its albums
else {
title.innerHTML = "Albums by " + band; // Display title
if (result[0].album.length == 0) // If no albums, say so
albumlist.innerHTML = "No albums found.";
else // Display the list
albumlist.innerHTML = result[0].album.join("<br>");
}
});
}
// Find names of bands matching the user's partial input
function searchForBands(band) {
// The Metaweb.search function will translate this object into
// URL parameters for the search service.
var query = {
prefix: band, // Prefix search
type: "/music/artist", // for bands (using default type_strict:all)
};
Metaweb.search(query, function(results) {
// If the search returns no results then we don't know what band
if (results.length == 0) {
document.getElementById("title").innerHTML = "Unknown Band"
document.getElementById("albumlist").innerHTML = "";
}
// Otherwise, display a list of links to possible bands
else {
document.getElementById("title").innerHTML = "Do you mean..."
var links = new Array(results.length);
for(var i = 0; i < results.length; i++) { // For each result
var band = results[i].name; // Get band name
links[i] = '<a href="javascript:listAlbums(\'' + // make link
band.replace("'","\\'") + '\')">' +
band + '</a>';
}
// Output list of links
document.getElementById("albumlist").innerHTML=links.join("<br>");
}
});
}
</script>
</head>
<body>
<!-- The HTML form for entering a band name -->
<form onsubmit="listAlbums(this.band.value); return false;">
<b>Enter the name of a band: </b>
<input type="text" name="band">
<input type="submit" value="List Albums">
</form>
<hr>
<!-- This is where we insert the results of our Metaweb queries -->
<h1 id="title"></h1> <!-- display band name here -->
<div id="albumlist"></div> <!-- list of albums here -->
</div>
</body>
</html>
EMQL
the search api can be used from inside MQL with an extension.
[{
"search": {
"query": "toronto",
"score": null,
"type": "/event/event",
"type_strict": "should"
},
"name": null,
"id": null,
"limit": 15,
"sort": "-search.score"
}]
[{%22search%22%3A{%22query%22%3A%22toronto%22%2C%22score%22%3Anull%2C%22type%22%3A%22%2Fevent%2Fevent%22%2C%22type_strict%22%3A%22should%22}%2C%22name%22%3Anull%2C%22id%22%3Anull%2C%22limit%22%3A15%2C%22sort%22%3A%22-search.score%22}&env={%22extended%22:1} example]
Interpreting Relevance results
(need helpful hints here)