Freebase MQL to list out all commons types for a given word? - json

I'm trying to figure out how to write a MQL query to get a list of all the types associated to a given word.
For example I tried:
{
"id":null,
"name":null,
"name~=": "SOME_WORD",
"type":"/type/type",
"domain": {
"id": null,
"/freebase/domain_profile/category": {
"id": "/category/commons"
}
}
}​
I found this to list out all the Commons types or categories but haven't yet figured out how to narrow it down for a given input.
[{
"id": null,
"name": null,
"type": "/freebase/domain_profile",
"category": {
"id": "/category/commons"
}
}]​

There are a couple of different ways to do this with different tradeoffs for each.
Use the Search API with a query like this
https://www.googleapis.com/freebase/v1/search?indent=true&filter=%28all%20name{full}:%22uss%20constitution%22%29
You'll get back JSON results which look like this:
{
"status": "200 OK",
"result": [
{
"mid": "/m/07y14",
"name": "USS Constitution",
"notable": {
"name": "Ship",
"id": "/boats/ship"
},
"lang": "en",
"score": 1401.410400
},
...
You can make the matching more liberal by switching the "{full}" to "{phrase}" which will give you a substring match instead of an exact match.
Caveats:
- You'll only get a single "notable type" and it's fixed by Freebase's (unknown) algorithm
- I don't think there's a way to get both USS Constitution & U.S.S. Constitution results
- You can get a list of all types by adding &mql_output={"type":[]}, but then you lose the "notable" type. I don't think there's a way to get both in a single call.
Use MQL
This query returns the basic information that you want:
[{
"name~=":"uss constitution",
"type":[],
"/common/topic/notable_types" : []
}]​
Caveats:
It won't find "uss constitution" which is an alias rather than the primary name (there's a recipe in the MQL cookbook for that though)
It won't find "u.s.s. constitution"
The "notable_types" API is an MQL extension and MQL extensions aren't supported in the new Freebase API, only the legacy deprecated API
You're tied to whatever (unknown) algorithm Freebase used to compute "notability"
Depending on what you are trying to accomplish, you might need something more sophisticated than this (as well as a deeper understanding of what's in Freebase), but this should get you going with the basics.

Did you try:
[{
"name": "David Bowie",
"type": []
}]

Related

Is returning only IDs for a JSON API collection allowed?

So let's say I have a resources called articles. These have a numeric id and you can access them under something such as:
GET /articles/1 for a specific article.
And let's say that returns something like:
{
"data": {
"type": "articles",
"id": "1",
"attributes": {
"title": "JSON:API paints my bikeshed!",
"body": "A bunch of text here"
}
}
}
Now my question is how to handle a request to GET /articles. I.e. how to deal with the request to the collection.
You see, accessing the body of the article is slow and painful. The last thing I want this REST API to do is actually try to get all that information. Yet as far as I can tell the JSON API schema seems to assume that you can always return full resources.
Is there any "allowed" way to return just the IDs (or partial attributes, like "title") under JSON API while actively not providing the ability to get the full resource?
Something like:
GET /articles returning:
{
"data": [
{
"type": "article_snubs",
"id": 1,
"attributes": {
"title": "JSON:API paints my bikeshed!"
}
}, {
"type": "article_snubs",
"id": 2,
"attributes": {
"title": "Some second thing here"
}
}
]
}
Maybe with links to the full articles?
Basically, is this at all possible while following JSON API or a REST standard? Because there is absolutely no way that GET /articles is ever going to be returning full resources due to the associate cost of getting the data, which I do not think is a rare situation to be in.
As far as I understand the JSON API specification there is no requirement that an API must return all fields (attributes and relationships) of a resource by default. The only MUST statement regarding fields inclusion that I'm aware of is related to Sparse Fieldsets (fields query param):
Sparse Fieldsets
[...]
If a client requests a restricted set of fields for a given resource type, an endpoint MUST NOT include additional fields in resource objects of that type in its response.
https://jsonapi.org/format/#fetching-sparse-fieldsets
Even so this is not forbidden by spec I would not recommend that approach. Returning only a subset of fields makes consuming your API much harder as you have to consult the documentation in order to get a list of all supported fields. It's much more within the meaning of the spec to let the client decide which information (and related resources) should be included.
The "attributes" object of a JSON-API doc does not need to be a complete representation:
attributes: an attributes object representing some of the resource’s data.
You can provide a "self" link to get the full representation, or perhaps even a "body" link to get just the body:
links: a links object containing links related to the resource.
E.g.
{
"data": [
{
"type": "articles_snubs",
"id": "1",
"attributes": {
"title": "JSON API paints my bikeshed!"
},
"links": {
"self": "/articles/1",
"body": "/articles/1/body"
}
},
{
"type": "article_snubs",
"id": "2",
"attributes": {
"title": "Some second thing here"
},
"links": {
"self": "/articles/2",
"body": "/articles/2/body"
}
}
]
}

How to store different kind of datas in single bucket in couchbase

I want to store the diff kind of data in same bucket in Couchbase, am googled its suggest doc_type and type parameter , but i don't know how i implement that one in my data,I tried below code but i don't know how to do that?
i didn't seen any example,any help will be appreciate,
JsonObject doc = JsonObject.fromJson(consumerRecord.value().toString());
String id=consumerRecord.key().toString();
bucket.upsert(JsonDocument.create(id, doc));
Couchbase buckets store documents of any kind. You don't have to do anything special. As long as it's valid JSON, it can be stored in a Couchbase bucket.
Now, what you might want is some way to differentiate between different types of documents (for querying purposes, for instance). So, you can put a "type" field (or docType or whatever you'd like) as a kind of 'marker' value. You can see examples of this in the built-in travel-sample bucket. For instance, look at the airline_10 and the route_10000 documents:
airline_10
{
"callsign": "MILE-AIR",
"country": "United States",
"iata": "Q5",
"icao": "MLA",
"id": 10,
"name": "40-Mile Air",
"type": "airline"
}
route_10000
{
"airline": "AF",
"airlineid": "airline_137",
"destinationairport": "MRS",
"distance": 2881.617376098415,
"equipment": "320",
"id": 10000,
"schedule": [ ... ],
"sourceairport": "TLV",
"stops": 0,
"type": "route"
}
Notice that one has a type of "airline", the other has a type of "route". An example of a query to find routes:
SELECT t.*
FROM `travel-sample` t
WHERE t.type = 'route'
LIMIT 10
This is one way to differentiate documents. Also notice that the keys are constructed semantically, so they could also be used. Neither of these are a requirement, so it really depends on how you plan to access documents.

How to build One-To-Many relationships within JSON API

I`m very new to JS/APIs/JSON.
I`ve got an API I built using deployd, a great tool that allows to to quickly set up an API.
My API called "app" has two resources zips and people. Each entry/object in zips has only one property zipcode. Each people has the properties name and phonenumber.
I want to figure out a way to have people be associated with various zipcodes. Either one or many if necessary. This would, as I understand, involve adding a property to people such as assoczipcodes and using a relationship model to indicate with zipcodes are related.
I've done some research here about how a relationship is structured but I simply don't understand the syntax and format.
Q: What datatype is correct for associzipcodes?
Q: What do I enter into each assoczipcodes to indicate which zips are related?
Cristik's answer appears to be outdated. According to the current documentation, you'd want to nest the relationship like this:
{
"type": "people",
"id": "1",
"attributes": {
"name": "John Doe"
},
"relationships": {
"zipcodes": {
"links": {
"self": "http://myserver.com/people/1/zipcodes"
}
}
}
}
Based on the contents from the Resource Relationships section, the simplest approach would be to return an URL for the relationship, and have that URL return all information needed:
{
"type": "people",
"id": "1",
"name": "John Doe",
"links": {
"zipcodes": "http://myserver.com/people/1/zipcodes"
}
}

Get list of dishes and detail per dish page in Freebase?

I tried this query to get the list of all dish instances
[{
"id": null,
"name": null,
"type": "/food/dish"
}]
But it only gives me first page:
http://www.freebase.com/query?autorun=1&q=%5B%7B%22id%22:null,%22name%22:null,%22type%22:%22/food/dish%22%7D%5D
Question 1: How to add paging to get all 2.5K or so dish instances? I tried to add "cursor: 2" and didn't work.
Let say I have a name "pizza", I tried this query to get detail of "pizza":
{
"*": null,
"name": "pizza",
"type": "/food/dish"
}
But that didn't give me description and images like this page http://www.freebase.com/m/0663v
Question 2: How to get all information, or at least description and image URLs like in the freebase page above?
Bonus: I tried to do everything via Freebase Node.js here https://github.com/spencermountain/Freebase.js
I suggest you separate this into 2 questions, so each has their own topic, and it is easier for future visitors to search.
That said:
Question 1
You can increase the number of results you get per page by adding limit: to your query. Regardless, you will have to use paging. To use paging, you need to add the cursor parameter to your mqlread HTTP request. Again: cursor is not part of the MQL query itself, but rather of the HTTP envelope that submits it.
For the first query, issue an empty cursor, and for subsequent queries use the cursor value returned to you by mqlread.
Note that all this will need to be done with the API, not with freebase directly, and as such the URL will need to be:
https://www.googleapis.com/freebase/v1/mqlread?cursor=&query=[{"id":null,"name":null,"type":"/food/dish","limit":5}]
Also note that if you plan on doing this for anything other than testing you will need to obtain a key from Google.
Finally, note that some strings in Freebase are "freebase-encoded", read up on that regarding how to decode them in the result.
Question 2
If you just want the ingredient names then simply add "/dining/cuisine/ingredients": [] to your query. Note that many dishes do not have ingredients, but Pizza does:
{
"id": "/m/0663v",
"name": null,
"type": "/food/dish",
"/dining/cuisine/ingredients": []
}
Getting the images means adding "/common/topic/image": [{}] to your query, and using the returned id for each image.
Getting an image URL from a given image id is done by prepending https://usercontent.googleapis.com/freebase/v1/image/ to the id.
Edit
Tom correctly noted that I forgot about image descriptions. The description for each image will be available under name: in the returned /common/topic/image array. For example, for the query
[{
"id": "/en/minestrone",
"/common/topic/image": [{
"id": null,
"name": null
}]
}]
you get the following images and their descriptions:
{
"result": [{
"id": "/en/minestrone",
"/common/topic/image": [
{
"id": "/wikipedia/images/commons_id/1492185",
"name": "MinestroneSoup"
},
{
"id": "/wikipedia/images/commons_id/12565901",
"name": "Homemade minestrone"
}
]
}]
}
Your final MQL, then, is:
[{
"id": null,
"name": null,
"type": "/food/dish",
"/common/topic/image": [{
"id": null,
"name": null
}],
"/dining/cuisine/ingredients": []
}]
... and the HTTP envelope will contain a key and a value for cursor.
See Nitzan's answer for the answer to question 1.
For your second question, the easiest way to get descriptions and images is by using the Topic API e.g. https://www.googleapis.com/freebase/v1/topic/m/0663v

Identifying Duplicates in CouchDB

I'm new to CouchDB and document-oriented databases in general.
I've been playing around with CouchDB, and was able to get familiar with creating documents (with perl) and using the Map/Reduce functions in Futon to query the data and create views.
One of the things I'm still trying to figure out is how to identify duplicate values across documents using Futon's Map/Reduce.
For example, if I have the following documents:
{
"_id": "123",
"name": "carl",
"timestamp": "2012-01-27T17:06:03Z"
}
{
"_id": "124",
"name": "carl",
"timestamp": "2012-01-27T17:07:03Z"
}
And I wanted to get a list of document id's that had duplicate "name" values, is this something I could do with the Futon Map/Reduce?
The result was hoping to achieve is as follows:
{
"name": "carl",
"dupes": [ "123", "124" ]
}
..or..
{
"carl": [ "123", "124" ]
}
.. which would be the value, and associated document ids which contain those duplicate values.
I've tried a few different things with Map/Reduce, but so far as I understand, the Map function works with data on a per-document basis, and the Reduce functions only allow you to work with the keys/values from a given document.
I know i could just pull the data I need with perl, work magic there, and get the result I want, but I'm trying to work only with CouchDB for now in order to better understand it's benefits / limitations.
Another way I'm thinking about doing this is to use a single document like an RDBMS table:
{
"_id": "names",
"rec1": {
"_id": "123",
"name": "carl",
"timestamp": "2012-01-27T17:06:03Z"
},
"rec2": {
"_id": "124",
"name": "carl",
"timestamp": "2012-01-27T17:07:03Z"
}
}
.. which should allow me to use the Map/Reduce functions in the way I originally thought. However I'm not sure if this is ideal.
I understand that my mind is still stuck in RDBMS land, so much of what I'm trying to do above may not be necessary. Any insight on this would be much appreciated.
Thanks!
Edit: Fixed JSON syntax in some of the examples.
If you merely want a list of unique values, that's pretty easy. If you wish to identify the duplicates, then it gets less easy.
In both cases, a map function like this should suffice:
function (doc) {
emit(doc.name);
}
For your reduce function, just enter _count.
Your view output will look like: (based on your 2 documents)
{
"rows": [
{ "key": "carl", "value": 2 }
]
}
From there, you will have a list of names as well as their frequency. You can take that list and filter it yourself, or you can take the "all couch" route and use a _list function to perform that final filtering.
function (head, req) {
var row, duplicates = [];
while (row = getRow()) {
if (row.value > 1) {
duplicates.push(row);
}
}
send(JSON.stringify(duplicates));
}
Read up about _list functions, they're pretty handy and versatile.