We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 4 years ago.
Improve this questionI have a city name field I am getting value from (i.e. randomly formatted), such as "NEW YORK", "new york" or "new-york" or "ny".
Having that field's value, I need to present user with a list of cities that have that value in their name in this format:
NY – New York City – 10001 MN – New York Mills – 56567Efficiency and performance is important. I can use JavaScript or PHP in order to retrieve this data.
So far, I've tried to use Freebase API. Here's an example query I've used: http://tinyurl.com/3ogpf7k
And here's JavaScript code I am using:
// App.q contains city name field's value
var query = {
extended : 1,
query : [{
search : App.q,
type : '/location/citytown',
id : null,
name : null,
postal_codes : [],
"/location/location/containedby" : [{
"type" : "/location/us_state",
"name": null,
// two letters abbreviation of state
"/common/topic/alias" : []
}]
}]
},
url = 'http://www.freebase.com/api/service/mqlread?callback=?&query=' +
encodeURIComponent(JSON.stringify(query));
$.getJSON(url, function( data ) {
var cities, i, len, name, aliases, j, abbr, postal_code, HTML = [];
for ( i = 0, len = data.result.length; i < len; i += 1 ) {
// cities with names matching user's input
if ( data.result[ i ].name.toLowerCase().indexOf( App.q ) === -1 ) continue;
// cities that have postal_codes data available
if ( data.result[ i ].postal_codes.length === 0 ) continue;
name = data.result[ i ].name;
aliases = data.result[ i ]["/location/location/containedby"][0]["/common/topic/alias"];
postal_code = data.result[ i ].postal_codes[0];
// find two-letters alias
for ( j = aliases.length - 1; j >= 0; j -= 1 ) {
if ( aliases[j].length === 2 && aliases[j] === aliases[j].toUpperCase() ) {
abbr = aliases[j];
}
}
HTML.push( D.renderHTML( liTemplate, {
name : name,
abbr : abbr,
postal_code : postal_code
}) );
}
console.log( HTML.join('') );
});
However, querying "New York" doesn't seem to return even "New York City".
Is there a better API that satisfies my need? Am I doing something wrong with Freebase API?
UPD. Another helpful API that allows to do kind of the same (it still doesn't cut my needs though – too many results and no way of paging through them):
Docs: http://www.geonames.org/export/web-services.html Example: http://api.geonames.org/postalCodeSearch?placename=los%20angeles&username=demo&maxRows=500Thanks!
Sorry about the previous misleading answer. I didn't notice that you were using the MQL extension "search" rather than the "name" property.
The main problem is that the default ordering is not by search score (not sure why, but that's the way it is). Modifying your query like this should fix things:
"search": {"query":"New York","score":null,"type_strict":"all"},
"sort":"-search.score",
"type":"/location/citytown",
The sort parameter is sorting in descending order by the "score" value returned from the "search" subquery. You could also use the mql_filter parameter for search to have it not even consider things which fail to meet your constraint (slightly more efficient).
The search extension is documented here and the document for the underlying search service that is uses are here
精彩评论