How do I update a non-unique property in Freebase? - freebase

I've been working on a calorie counter and I'm slowly making progress on my MQL write. The issue that I'm having currently is updating the recipe itself which is in the /common/topic/description property.
The query that I am using currently is:
[{
id: recipeId, // previously retrieved
'/common/topic/description': {
connect: 'replace',
value: $('#description textarea').val(),
lang: '/lang/en'
}
}]
This succeeds in executing, but when I query (another) after it has run I get an error:
{
"domain": "global",
"reason": "invalid",
"message": "Unique query may have at most one result. Got 2",
"locationType": "other",
"location": "/common/topic/description"
}
According to the documentation, connect: replace does an update on unique properties and an insert on non-unique ones. So am I getting that because a value was inserted?
Is it necessary to remove the other value to prevent the error? Do I need to know the existing value in order to remove it?
{
id: recipeId,
'/common/topic/description': {
connect: 'delete',
value: 'Value currently stored',
lang: '/lang/en'
}
}

The problem doesn't anything to do with updating non-unique properties. Your read query is the issue. You didn't quote the failing query, but the part of the error message that says "location": "/common/topic/description" is your hint. That topic has two descriptions, one empty and one not, but you haven't used array notation in you query.
This will work:
[{
"id": "/m/0wh83sg",
"/food/recipe/ingredients": [{
"id": null,
"ingredient": {
"id": null,
"name": null,
"/food/food/energy": null,
"/common/topic/image": {
"id": null,
"optional": true,
"limit": 1
},
"optional": true
},
"unit": {
"id": null,
"name": null,
"optional": true
},
"quantity": null,
"notes": null
}],
"/common/topic/description": [{}]
}]

Related

In freebase MQL, how do I query for properties that may not have content?

Say I'm trying to get properties from a film. I can run the following which will return an array of actors:
{"type":"/film/film","id":"/m/05ggnq",
"starring":[{"mid":null,"actor":null,"character":null}]
}
However, when I try to query for another property that may or may not exist ("story_by") I simply get back an empty 200 response.
{"type":"/film/film","id":"/m/05ggnq", "story_by":[{"mid":null}],
"starring":[{"mid":null,"actor":null,"character":null}]
}
How am I suposed to search for both of these properties at the same time?
You can do this using the optional directive like this:
{
"type": "/film/film",
"id": "/m/05ggnq",
"story_by": [{
"mid": null,
"optional": true
}],
"starring": [{
"mid": null,
"actor": null,
"character": null
}]
}

Freebase MQL query retrieving inconsistent results

When I run this query in the freebase query builder
[{
"/type/object/id": "/en/michael_jackson",
"/type/object/name": null,
"/type/object/type": "/music/artist",
"/music/artist/album": [{
"id": null,
"name": [],
"release_type!=": "Single",
"/music/album/primary_release": [{
"name": null,
"track_list": [{name:null}]
}]
}]
}];​
I get back the proper results, with album and track listing but if change the query to
[{
"/type/object/id": "/en/carly_rae_jepsen",
"/type/object/name": null,
"/type/object/type": "/music/artist",
"/music/artist/album": [{
"id": null,
"name": [],
"release_type!=": "Single",
"/music/album/primary_release": [{
"name": null,
"track_list": [{name:null}]
}]
}]
}];​
I dont get back anything. You can try both of these queries at http://www.freebase.com/queryeditor. Can somebody point out what am I doing wrong? Both of these are artist, so I should get back abum and track listing for Carly Rae Jepsen also.
Not all albums have a primary release recorded. Unless you really care about this, I'd loosen your constraints and use a query like this:
[{
"id": "/en/carly_rae_jepsen",
"name": null,
"type": "/music/artist",
"/music/artist/album": [{
"id": null,
"name": null,
"release_type!=": "Single",
"/music/album/releases": [{
"name": null,
"track_list": [{"name":null}]
}]
}]
}]​
Some other tweaks to the query:
the last "name" wasn't quoted
queries aren't terminated by a semicolon
/type/object is the default and can be omitted, similarly with properties associated with the most recently specified type
name is a single valued property, so one uses null as opposed to []
If you want the primary release if available, but not have it constrain your query, you can use "optional":true. You could get even fancier by sorting all releases by release date and only taking the first one (on the assumption that that's got a good chance of being the primary release).
The resulting query would look like this:
[{
"id": "/en/carly_rae_jepsen",
"name": null,
"type": "/music/artist",
"album": [{
"id": null,
"name": [],
"release_type!=": "Single",
"primary_release": [{
"optional": true,
"name": null,
"track_list": [{
"name": null
}]
}],
"releases": [{
"name": null,
"track_list": [{
"name": null
}],
"release_date": null,
"sort": "release_date",
"limit": 1
}]
}]
}]​

Related information about location in freebase are always null?

I'm trying to query freebase to find information about a specific city.
I'm able to find the city that I'm looking for but I need to get the description content as well as a few pictures.
My current query is
[{
"name": "san francisco",
"id": null,
"type": "/location/citytown",
"/location/location/geolocation" : [
{
"latitude": null,
"longitude": null,
"latitude>" : 36,
"latitude<" : 38 }]
"/common/topic/article" : [{ "id" : null, "content": null }],
"/common/topic/image" : [{
"id" : null,
"optional" : true,
"limit" : 15
"image_caption" : []
}]
}]
Which returns
{
"code": "/api/status/ok",
"result": [{
"/common/topic/article": [{
"content": null,
"id": "/m/0d6l_"
}],
"/common/topic/image": [
{
"id": "/m/02929wx",
"image_caption": []
},
{
"id": "/m/04j74y4",
"image_caption": []
},
{
"id": "/m/04j74yh",
"image_caption": []
},
{
"id": "/m/04j74yw",
"image_caption": []
},
{
"id": "/m/04j74z6",
"image_caption": []
}
],
"/location/location/geolocation": [{
"latitude": 37.775,
"longitude": -122.4183
}],
"id": "/en/san_francisco",
"name": "San Francisco",
"type": "/location/citytown"
}],
"status": "200 OK",
"transaction_id": "cache;cache03.p01.sjc1:8101;2012-07-24T21:50:06Z;0029"
}
I can't get the content value and the captions to be set.
Am I missing something ?
Where did you find the "image_caption" property? If you switch it to "name" you should get the names of the images (which are used as captions in some UI contexts).
The text content isn't available from MQL, but you can get it from the BLOB service in the old API or the text API in the new APIs using the ID that is returned for the article. e.g. https://www.googleapis.com/freebase/v1/text/m/0d6l_
p.s. If you just want the primary image, you might consider using the Topic API which will return you the image, it's name, the text blurb, and a bunch of other info in a single call.
https://www.googleapis.com/freebase/v1/topic/wikipedia/en_id/49728
Using the Search API will give you more robust name matching as well as give you a score which will tell you how likely it is that the query is ambiguous (if you get multiple matches with scores close to each other).
https://www.googleapis.com/freebase/v1/search?query=%22san%20francisco%22&type=/location/citytown

Freebase retrieve not edited data

In addition to this question:link i'm asking if i can retrieve data like the text or even geolocation from topics that seems that they have not any info been entered(but there is text description from wikipedia)
So, the problem is that when you run the following query you don't get any results:
[{
"name": "River Thames",
"type": "/location/location",
"geolocation": [{
"latitude": null,
"longitude": null
}],
"/common/topic/article": [{
"text": {
"maxlength": 16384,
"chars": null
}
}]
}]​
Try it out
This is because Freebase doesn't have geocoordinates (yet) for a topic called "River Thames". In other words, there are no combination of facts in Freebase that will match this query structure exactly so it returns nothing. It does however have coordinates for the mouth of the river so you will get results for this similar query:
[{
"name": "River Thames",
"type": "/location/location",
"/geography/river/mouth_long_lat": [{
"latitude": null,
"longitude": null
}],
"/common/topic/article": [{
"text": {
"maxlength": 16384,
"chars": null
}
}]
}]​
Try it out
But what should you do if you don't know beforehand whether the data that you're looking for is completely filled out in Freebase yet?
You can mark certain parts of a query as being "optional" which means that they should be returned if the data is present but that the query should still return results even if that data isn't present. So for your original query that would look like this:
[{
"name": "River Thames",
"type": "/location/location",
"geolocation": [{
"latitude": null,
"longitude": null,
"optional": true
}],
"/common/topic/article": [{
"text": {
"maxlength": 16384,
"chars": null
}
}]
}]​
Try it out
Now you should get results with the text of the article present but the geolocation returned as an empty array.
One more thing I should point out is that you should be aware that the query you've written is asking for a list of ALL topics in Freebase with the name "River Thames". Right now, that query only returns one result but in the future, when more data is added to Freebase, it may return multiple results. If you're really only interested in THIS River Thames, you should query it using its unique MID like this:
{
"id": "/m/0d2kt"
"name": null,
"type": "/location/location",
"geolocation": [{
"latitude": null,
"longitude": null,
"optional": true
}],
"/common/topic/article": [{
"text": {
"maxlength": 16384,
"chars": null
}
}]
}​
Try it out

Freebase MQL Test for Not True

I have a simple script that retrieves all of the Freebase types within a domain. Now I want to filter out the CVT types, but I can't figure out how to write that test. If I write it the way that seems most obvious:
<acre:script>
var q_categories = [{
"id": null,
"name": null,
"sort": "name",
"type": '/freebase/domain_category',
"domains": [{
"id": null,
"name": null,
"sort": "name",
"!/type/type/domain": [{
"id": null,
"name": null,
"sort": "name",
"/freebase/type_hints/mediator!=": true
}],
}]
}];
var categories = acre.freebase.mqlread( q_categories ).result;
</acre:script>
I get an error:
JS exception: acre.freebase.Error: /api/status/error: Can't use comparison operators on boolean values
I'm guessing that this may be a use case for the "optional": "forbidden" directive, but I'm not sure how to structure the syntax even if my guess is correct.
Any nudge in the right direction would be much appreciated.
This should work:
"/freebase/type_hints/mediator": {
"optional": "forbidden",
"value": true
}
P.S. I suggest working in the Query Editor when you're trying to develop a query.
Here's a working example of the query using optional:forbidden. http://tinyurl.com/2co63sy

Resources