Базы знаний. Часть 2. Freebase: делаем запросы к Google Knowledge Graph

в 12:37, , рубрики: Без рубрики

image
Больше года назад Google объявил, что отныне в их поиске используется таинственная Сеть Знаний (официальный перевод Knowledge Graph). Возможно, не все знают, что значительная часть данных Сети доступна для использования всеми желающими и доступна по прекрасно описанному API. Этой частью является база знаний Freebase, поддерживаемая Google и энтузиастами. В этой статье мы сначала немного подурачимся, а потом попробуем сделать несколько простеньких запросов на языке MQL.
Эта статья — вторая из цикла Базы знаний. Следите за обновлениями.

  • Часть 1 — Введение
  • Часть 2 — Freebase: делаем запросы к Google Knowledge Graph
  • Часть 3 — Dbpedia — ядро мира Linked Data
  • Часть 4 — Wikidata — семантическая википедия

Google Knowledge Graph с точки зрения рядового пользователя

Одним из видимых проявлений Google Knowledge Graph являются информационные панели, кратко описывающие тот объект, который вы ищете. Они часто возникают при поиске персоналий, чуть реже — географических наименований. Они чаще возникают для запросов, заданных на английском языке в английском интерфейсе, но мы будем придерживаться русского языка там, где это возможно.
Например, запрос Роджер Уотерс даёт следующий результат:
image

Покликайте по ссылкам в инфобоксе и обратите внимание на URL — в нем используется параметр stick, содержимым которого является некоторый идентификатор вида &stick=H4sIAAAAAAAAAONg[VuLQz9U3]<сам идентификатор>AAAA
Когда Knowledge Graph только появился, это позволяло демонстрировать непосвященным небольшую уличную магию, например, добавлять &stick-параметр от Мерилин Монро к запросу от Стивена Кинга:
image

Сейчас такую возможность прикрыли, да и ни к чему она нам — лучше посмотрим на что-нибудь полезное. К примеру, недавно появилась возможность сравнить несколько объектов с помощью ключевого слова vs:

image

Гугл обещает добавить еще много вкусностей, связанных с умным поиском и ответами на вопросы, и Knowledge Graph будет одним из столпов, на котором эта интеллектуальность держится. Что особенно прекрасно для нас, так это то, что кусочек Knowledge Graph'a открыт для использования всеми желающими.

Freebase — подграф GNG

Начнем с исторического экскурса. Компания Metaweb начала работу над своей базой знаний в 2005 году. По способу наполнения данными Freebase больше всего походила на Dbpedia: львиную долю знаний, представленных во Freebase, являлись данные из Википедии. Отличием от Dbpedia была, во-первых, возможность поправлять введенные данные вручную, а во-вторых то, что Freebase не гнушалась и другими источниками данных. В отличии от команды DBpedia, представители Metaweb не слишком заботились о том, чтобы публиковать научные статьи (хотя в последнее время начали, вот тут интересный список), и признавались, что код основного компонента, graphd, вряд ли когда-нибудь увидит свет дня.
В 2010 году компания Metaweb была куплена Google, но, судя по рассылке Freebase, поисковый гигант не слишком вмешивался в дела свежеприобритенной команды. После выпуска красочного ролика, в котором Google рвет конкурентов, как пионерскую правду с помощью своих новых интеллектуальных семантических технологий, представители Metaweb (а затем и Google) подтвердили, что Freebase является очень важной частью Сети Знаний, наряду с Википедией и базой фактов ЦРУ. Во время большого субботника по унификации всех гугловых API, программный интерфейс Freebase сильным изменениям подвергать не стали, а его описание просто перенесли на developers.google.com. Для того, чтобы спросить что-нибудь у базы знаний мы по-прежнему используем язык запросов MQL (произн. «микл», Metaweb Query Language). За дело!

Первый запрос и редактор

Начнем с простенького вопроса: спросим у Freebase какой-нибудь факт, например дату рождения Леонардо да Винчи:
https://www.googleapis.com/freebase/v1/mqlread?query={"/type/object/id":"/en/leonardo_da_vinci","/people/person/date_of_birth":null}
Получим вполне корректный результат:

{
 "result": {
 "/type/object/id": "/en/leonardo_da_vinci", 
 "/people/person/date_of_birth": "1452-04-15"
}
}

Для того, чтобы нам было проще упражняться, мы будем использовать редактор запросов, любезно предоставляемый Freebase.
image
Редактор этот страшно удобен и имеет прекрасную функцию автодополнения запросов — в случае затруднений просто нажмите Ctrl+Enter и вы получите отличные контекстные подсказки. В нижней панели редактора расположились полезные инструменты, которые подробно описаны в руководстве. При самостоятельном изучении особенно советуем поглядеть на кнопку examples, содержащую примеры запросов, проясняющим многие возможности MQL.

Ну что, вот наш запрос, а вот ответ на него:

Запрос Ответ
{
  "id":   "/en/leonardo_da_vinci",
  "/people/person/date_of_birth" : null
}
{
    "id":   "/en/leonardo_da_vinci"
    "/people/person/date_of_birth": "1453-04-15",
  }

Разберем этот запрос подробнее. Мы указали идентификатор объекта во Freebase с помощью термина id. Идентификаторы есть у всех объектов, а слово id является сокращением от /type/object/id. Есть много других /type/object свойств, которыми обладают все сущности Freebase, они будут рассмотрены чуть позже.
Объект, имеющий идентификатор /en/leonardo_da_vinci, возможно, обладает свойством /people/person/date_of_birth, значения которого мы не знаем. Мы ставим вместо этого значения специальное слово null, на место которого в ответе Freebase запишет значение из базы.
Как легко заметить, запрос и ответ на него симметричны.

Сложный запрос

Теперь, для того, чтобы возникло побольше вопросов, мы составим достаточно сложный MQL-запрос и вкратце его объясним. После этого можно будет приступить к подробному изучению структуры Freebase и обзору возможностей языка.

Итак, вот наш запрос (взят из руководства по MQL):

Запрос Ответ
  1. [{
  2.   "type":    "/music/album",
  3.   "name":    null,
  4.   "name!=":  "Greatest Hits",
  5.   "release_date|=": [
  6.     "1978",
  7.     "1979"
  8.   ],
  9.   "genre":[],
  10.   "a:genre": "New Wave",
  11.   "b:genre|=": [
  12.     "Punk Rock",
  13.     "Post-punk",
  14.     "Progressive rock"
  15.   ],
  16.   "artist": {
  17.     "name": null,
  18.     "type": {
  19.       "id":       "/people/person",
  20.       "optional": "forbidden"
  21.     }
  22.   },
  23.   "limit":2,
  24.   "sort":"name",
  25. }]

[{
    "type":     "/music/album",
    "name":     "Dawn of the Dickies",
    "a:genre":  "New Wave",
    "artist": {
      "name": "Television",
      "type": null
    },
    "genre": [
      "Punk rock",
      "New Wave",
      "Post-punk",
      "Protopunk"
    ],
    "ns0:name": "Adventure",
    "ns1:type": "/music/album"
  },
  {
    "a:genre": "New Wave",
    "artist": {
      "name": "The Dickies",
      "type": null
    },
    "genre": [
      "New Wave",
      "Punk rock"
    ]
}]

Попробуем вкратце описать, что за средства MQL использованы в данном запросе.
Во-первых, как можно видеть, весь запрос обернут в конструкцию [ { } ], что означает, что в качестве результата вы ожидаете массив объектов, а не один объект, как в случае с { }.
Строки 2-4 не должны вызывать каких-либо проблем: мы ищем объект типа альбом (/music/album), нам хочется получить его имя и нас не интересуют альбомы, называющиеся "Greatest Hits".
В строчках 5-8 и 11-15 появляется оператор ИЛИ |= — нас интересуют альбомы, у которых дата выхода равна 1978 или 1979 году. Перейдем теперь к жанру:

  "genre":[],
  "a:genre": "New Wave",
  "b:genre|=": [
    "Punk Rock",
    "Post-punk",
    "Progressive rock"
  ],

Первая строчка говорит о том, что нам хочется получить список жанров данных альбомов в ответе запроса. Для этого мы добавили в запрос пустой список [ ]. Дальше мы говорим, что нас интересуют только альбомы, в жанрах которых указаны New Wave И один из списка «Punk Rock», «Post-punk», «Progressive rock».
Наконец, строки 23-24 содержат директивы MQL: мне интересны только два результата (limit) и я хочу отсортировать их по имени (sort).

JSON в MQL

MQL-запросы и ответы на них являются JSON-объектами, поэтому для самых маленьких (или тех, кто не относится к веб-разработчикам) расскажу о JSON.

Общая информация про JSON

JSON (JavaScript Object Notation) — это язык, созданный для обмена данными в формате «ключ-значение». Изначально JSON использовался для сериализации объектов JavaScript, но быстро стал языконезависимым и благодаря своей простоте, стал очень любим и уважаем программистами на разных языках и платформах.
Самый простой JSON-объект — пустой объект. Он записывается следующим образом:

{}

Теперь давайте создадим объект, в котором хранится информация о Леонардо да Винчи. Для начала ограничимся только его именем. Для этого заключим ключ и значение в кавычки, разделив двоеточием

{
 "name" : "Leonardo di ser Piero da Vinci"
}

Добавляем несколько фактов о Леонардо, разделяя их через запятую:

{
 "name" : "Leonardo di ser Piero da Vinci",
 "date_of_birth": "1453-04-15",
}

Теперь стоит определить, что за профессия была у да Винчи. А профессий-то этих было много: и скульптор, и художник, и архитектор и еще много кто. Для того, чтобы присвоить одному ключу несколько значений, в JSON используются списки значений — заключенные в квадратные скобки значения, указанные через запятую:

{
 "name" : "Leonardo di ser Piero da Vinci",
 "date_of_birth": "1453-04-15",
 
 "profession": [
      "Architect",
      "Engineer",
      "Anatomist",
      "Inventor",
      "Artist",
      "Sculptor"
    ],
}

Еще одна вещь о JSON, которую стоит знать, — это вложенные объекты. Они делаются крайне просто: после ключа вы просто вставляете новый набор пар ключей-значений в фигурных скобках. В случае с Леонардо мы можем попробовать отобразить данные о месте рождения Леонардо — селе Анкиано, находящемся в Италии. Мы скажем, что ключ «place_of_birth» соответствует некоторому объекту с именем Anchiano, находящимся в Italy:

{
 "name" : "Leonardo di ser Piero da Vinci",
 "date_of_birth": "1453-04-15",
 "profession": [
      "Architect",
      "Engineer",
      "Anatomist",
      "Inventor",
      "Artist",
      "Sculptor"
    ],
 
 "place_of_birth": {
      "name": "Anchiano",
      "containedby": "Italy",
   },
}

Не совсем JSON

Вообще, MQL-запросы не являются корректными JSON-объектами. MQL — это надмножество JSON и в нём разрешаются разного рода вольности. Одна из идей продуктов Metaweb заключается в том, что программы должны уметь прощать пользователям ошибки и описки, которые те делают. Эта идея есть и в других языках и программах, а в первую очередь — в World Wide Web — ничего страшного, что некоторые части html написаны с ошибками, нужно все равно постараться отобразить документ.
Вот, например, корректный JSON-запрос, ищущий людей с редкой и ценной профессией:

{
   "id": "/en/pope",
   "/people/profession/people_with_this_profession": [{
   "name":  null,
   "limit": 4
  }]
}

Мы можем убрать кавычки и запрос продолжит работать:

{
   id: /en/pope,
   /people/profession/people_with_this_profession: [{
   name:  null,
   limit: 4
  }]
}

Закрывать скобочки и разделять пары двоеточием тоже не обязательно, так что вот пример совсем уж безобразия:

   id /en/pope
   /people/profession/people_with_this_profession [{
   name  null
   limit 4

Устройство Freebase

Официальное руководство дает очень хорошее введение в то, как хранятся данные внутри Freebase. Нам это не слишком важно, потому что используемые во Freebase четверки объектов полностью скрыты за объектной парадигмой. Если вам интересно, можете обратиться к соответствующей странице мануала
Итак, Freebase позволяет нам думать о том, что внутри него лежат объекты. Каждый объект ограничивается фигурными скобками { } и состоит из пар «свойство-значение», разделенных двоеточиями. Объекты, которые Freebase выдает в качестве ответов на MQL-запросы, являются корректными JSON-объектами, однако они не похожи на объекты парадигмы ООП. Лучше всего думать о них, как о неупорядоченных множествах пар.
В качестве свойства (то есть того, что стоит до двоеточия) в MQL могут стоять идентификаторы. В качестве значений могут быть идентификаторы, литералы, массивы и, наконец, вложенные объекты.Freebase имеет правила, по которым должны строиться идентификаторы. Идентификатор состоит из пространства имен и ключа, разделенных прямым слэшем /. Рассмотрим, например, идентификатор /people/person/date_of_birth — в нем date_of_birth является ключом, а /people/person — пространством имен.
Идентификаторы уникальны. Они не обязаны нести смысловой нагрузки, однако зачастую по идентификатору объекта легко понять, о чем идет речь.
image

Универсальные свойства объектов

Все объекты Freebase обладают следующими зарезервированными (универсальными свойствами):

  • имя — /type/object/name
  • ключ — /type/object/key
  • идентификатор — /type/object/id
  • тип (обычно больше одного) — /type/object/type
  • время создания — /type/object/timestamp
  • создатель — /type/object/creator
  • режим доступа — /type/object/permission
  • глобальный идентификатор — /type/object/guid
  • машинный идентификатор — /type/object/mid

Мы рассмотрим тут свойства, которые наиболее часто используются в MQL-запросах: имена, идентификаторы и типы.

Идентификаторы

Во Freebase как-то очень много идентификаторов. Самый главный из них /type/object/guid, даётся раз и навсегда. Есть его сокращенная форма /type/object/mid. Ну а пользуются в запросах обычно /type/object/id — он часто бывает человекочитабельным. Самое главное, это то, что не бывает двух объектов с одинаковыми идентификаторами. Так например, взгляните, как многих людей звали Адам Смит (Adam Smith): статья на английской Википедии. Только моральный философ Адам Смит носит гордый идентификатор /en/adam_smith. Все остальные Адамы Смиты будут идентифицироваться по другому, будь они политиками (/en/adam_smith_1965), футболистами (/en/adam_smith_huddersfield) или кем-либо другим.

Вы можете ввести идентификатор в поле поиска на Freebase.com и получить страницу свойств объекта:
image

Свойство /type/object/name

У каждого объекта есть имя. Имя — вещь не уникальная, у объекта обычно несколько имен — по одному на каждый язык. Самое интересное, что это нисколько не усложняет запросы — вы заметите, что при запросе имен вам будет выдаваться только имя на языке, установленном во Freebase как текущий. Так что можно обращаться с объектами типа name как с обычными строками.

Свойство /type/object/type

Это свойство задает тип объекта. У одного объекта может быть несколько типов — обычно так и бывает.
Если в запросе вы указали свойство type, то вы пространство имен для этого типа можно опускать. Какие свойства относятся к типу /film/director? Разумеется, те, которые находятся в пространстве имен этого типа, то есть те, что начинаются с /film/director. Рассмотрим, например, запрос всех фильмов, снятых Стэнли Кубриком. Слева показан запрос в сокращенной форме, которой мы и будем пользоваться дальше, а справа — то, как он мог бы выглядеть, не будь разработчики Metaweb так добры к нам.

Запрос Запрос в полной форме
[{
  "name": "Stanley Kubrick",
  "type": "/film/director",
  "film": [],
}]
[{
  "/type/object/name": "Stanley Kubrick",
  "/type/object/type": "/film/director",
  "/film/director/film" : []
}]

Во-вторых, все свойства из пространства имен /type/object можно опускать — именно поэтому мы имеет право писать просто id, name, type и т.д. Почему? Потому что все объекты в Freebase имеют тип Объект.

Различные виды MQL-запросов

Мы уже разобрали довольно много запросов, но пока не сосредотачивались на самом языке. В первую очередь, давайте посмотрим на то, как в MQL запрашиваются нужные значения. Бывают следующие случаи:

  • мне нужно запросить одно литеральное значение. Например, дату рождения человека
  • мне нужно запросить массив значений. Например список альбомов музыкальной группы.
  • мне нужно запросить один объект c его основными свойствами: идентификатором, основным типом и именем
  • мне нужно запросить массив объектов
  • мне нужно узнать всё об объекте

Запрос одного значения

Если вы хотите, чтобы Freebase вернул вам объект той же структуры, что и объект запроса, но с заполненным неизвестным полем, то в запросе надо вместо этого поля подставить null. Мы видели довольно много таких примеров, вот вам еще один. Спросим у музыканта Кита Эмерсона, откуда он родом:

Запрос Ответ
{
  "name": "Keith Emerson",
  "type": "/music/artist",
  "origin": null
}

{
  "result": {
    "name": "Keith Emerson",
    "origin": "England",
    "type": "/music/artist"
  }
}

Запрос массива значений

Если мы попробуем использовать null для запроса всех альбомов музыкальной группы, то мы получим ошибку. Если вы ожидаете массив объектов, используйте квадратные скобки []. Freebase заполнит этот массив строками, перечисленными через запятую. Примеров с альбомами музкалььных групп полно и в официальном руководстве, а мы найдем список книжек, написанных Хокингом:

Запрос Ответ
{
  "name": "Stephen Hawking",
  "type": "/book/author",
  "works_written": []
}

{
  "result": {
    "name": "Stephen Hawking",
    "works_written": [
      "The Universe in a Nutshell",
      "A Brief History of Time",
      "George's Secret Key to the Universe",

Там еще много

      "Computer Resources for People With Disabilities",
      "The Nature of Space and Time",
      "On the Shoulders of Giants",
      "Black Holes and Baby Universes and Other Essays",
      "George's Cosmic Treasure Hunt",
      "The Theory of Everything",
      "The Grand Design",
      "A Briefer History of Time",
      "God Created the Integers",
      "George and the Big Bang",
      "The Large Scale Structure of Space-Time",
      "The Illustrated Brief History of Time",
      "The Singularities of Gravitational Collapse and Cosmology",
      "Gravitational Radiation from Colliding Black Holes",
      "Black Holes in General Relativity",
      "Black Hole Explosions?",
      "The Development of Irregularities in a Single Bubble Inflationary Universe",
      "Wave Function of the Universe",
      "Information Loss in Black Holes",
      "The large scale structure of space-time",
      "General Relativity; an Einstein Centenary Survey",
      "Is the end in sight for theoretical physics?",
      "Black holes and baby universes and other essays",
      "A brief history of time",
      "My Brief History",
      "Vector Fields in Holographic Cosmology",
      "Inflation with Negative Lambda",
      "Accelerated Expansion from Negative Lambda",
      "The Dreams That Stuff Is Made Of: The Most Astounding Papers of Quantum Physics and How They Shook the Scientific World",
      "Local Observation in Eternal inflation",
      "The No-Boundary Measure in the Regime of Eternal Inflation",
      "The Classical Universes of the No-Boundary Quantum State",
      "No-Boundary Measure of the Universe",
      "Volume Weighting in the No Boundary Proposal",
      "The Measure of the Universe",
      "Populating the Landscape: A Top Down Approach",
      "A Non Singular Universe",

      "Black Holes and the Information Paradox"
    ],
    "type": "/book/author"
  }
}

Если вы напротив, запросите массив вместо одиночного значения – в этот нет никаких проблем – Freebase преобразует результаты и выдаст массив с одним-единственным значением.

Запрос объектов

Хорошо, но для моего приложения мне интересно знать не только названия книжек Хокинга, но и даты их выхода, и картиночки бы не помешали! Такое тоже возможно. Дело в том, что массив книг, который мы получили в прошлом запросе, только выглядит массивом строк. На самом деле, это массив объектов, просто Freebase сворачивает объекты в строки, оставляя только их свойство name.

Также и Англия, откуда родом наш музыкант, это не просто строка «England», а полноценный объект. Чтобы получить объектное представление в запросе, используется конструкция { }, вот так:

{
  "name": "Keith Emerson",
  "type": "/music/artist",
  "origin": { }
}

В результате нам выдадут самую важную информацию об объекте: его идентификатор, название и список типов:

результат запроса

{
  "result": {
    "origin": {
      "id": "/en/england",
      "name": "England",
      "type": [
        "/common/topic",
        "/location/location",
        "/film/film_subject",
        "/book/book_subject",
        "/location/administrative_division",
        "/film/film_location",
        "/location/uk_constituent_country",
        "/user/xleioo/winning_night/option_list",
        "/location/statistical_region",
        "/location/dated_location",
        "/symbols/name_source",
        "/m/04kp2w0",
        "/user/robert/military/military_power",
        "/symbols/flag_referent",
        "/user/skud/flags/topic",
        "/user/skud/names/topic",
        "/user/robert/military/topic",
        "/base/petbreeds/topic",
        "/m/04mp17s",
        "/user/xleioo/winning_night/topic",
        "/organization/organization_scope",
        "/base/charities/geographic_scope",
        "/sports/sports_team_location",
        "/base/thoroughbredracing/thoroughbred_racehorse_origin",
        "/user/tsegaran/random/taxonomy_subject",
        "/base/authors/country_of_origin",
        "/base/authors/topic",
        "/biology/breed_origin",
        "/fictional_universe/fictional_setting",
        "/government/political_district",
        "/olympics/olympic_participating_country",
        "/base/summermovies2009/topic",
        "/base/leicester/topic",
        "/base/popstra/location",
        "/location/country",
        "/base/england/topic",
        "/base/ontologies/ontology_instance",
        "/event/speech_topic",
        "/user/skud/legal/treaty_signatory",
        "/government/governmental_jurisdiction",
        "/base/masterthesis/topic",
        "/user/jamie/default_domain/yacht_racing/yacht_racing_country",
        "/base/horticulture/cultivar_origin",
        "/base/horticulture/topic",
        "/base/localfood/food_producing_region",
        "/base/localfood/topic",
        "/sports/sport_country",
        "/base/todolists/topic",
        "/base/tagit/concept",
        "/food/beer_country_region",
        "/periodicals/newspaper_circulation_area",
        "/location/uk_statistical_location",
        "/base/biblioness/bibs_location",
        "/base/biblioness/bibs_topic",
        "/base/aareas/schema/gb/constituent_country",
        "/base/aareas/schema/administrative_area",
        "/base/uncommon/topic",
        "/base/schemastaging/statistical_region_extra",
        "/people/place_of_interment",
        "/base/allthingsnewyork/topic",
        "/base/events/topic",
        "/base/events/geographical_scope",
        "/base/tonyfranksbuckley/topic",
        "/base/piratesofthewirralpeninsula/topic",
        "/military/military_combatant",
        "/military/military_post",
        "/organization/organization_member"
      ]
    },
    "name": "Keith Emerson",
    "type": "/music/artist"
  }
}

Вложенные запросы

Можно получить любую другую информацию о стране происхождения нашего музыканта, формируя, таким образом, вложенный запрос. Например, мне хочется узнать, на каком языке говорят в стране, откуда родом Эмерсон. Обратите внимание, я добавляю тип для страны, чтобы получать подсказки от редактора запросов:

Запрос Ответ
{
  "name": "Keith Emerson",
  "type": "/music/artist",
  "origin": {
    "type": "/location/country",
    "official_language": null
  }
}
{
  "result": {
    "name": "Keith Emerson",
    "type": "/music/artist",
    "origin": {
      "type": "/location/country",
      "official_language": "English Language"
    }
  }
}

Можно спуститься ниже: к какой языковой семье относится язык, на котором говорят в стране, откуда родом Эмерсон?

Запрос Ответ
{
  "name": "Keith Emerson",
  "type": "/music/artist",
  "origin": {
    "type": "/location/country",
    "official_language": {
      "type": "/language/human_language",
      "language_family": []
    }
  }
}
{
  "result": {
    "type": "/music/artist",
    "name": "Keith Emerson",
    "origin": {
      "type": "/location/country",
      "official_language": {
        "language_family": [
          "West Germanic languages",
          "Indo-European languages",
          "Anglo-Frisian languages"
        ],
        "type": "/language/human_language"
      }
    }
  }
}

Эти довольно дурацкие запросы легко обобщаются в нечто более полезное. Например, запрос на получение списка музыкантов, родом из англоговорящих стран. Обратите внимание, что я часто использую вывод в виде массива. Ну и еще на слово limit, которое ограничивает вывод тремя результатами:

Запрос Ответ
[{
  "name": null,
  "type": "/music/artist",
  "origin": [{
    "type": "/location/country",
    "official_language": "English Language"
  }],
  "limit": 3
}]
{
  "result": [
    {
      "origin": [{
        "type": "/location/country",
        "official_language": "English Language"
      }],
      "name": "The Katinas",
      "type": "/music/artist"
    },
    {
      "origin": [{
        "type": "/location/country",
        "official_language": "English Language"
      }],
      "name": "Shermain Jeremy",
      "type": "/music/artist"
    },
    {
      "origin": [{
        "type": "/location/country",
        "official_language": "English Language"
      }],
      "name": "Patsy Moore",
      "type": "/music/artist"
    }
  ]
}
Запрос всех свойств объекта

Полезная вещь при конструировании запроса — получить все свойства объекта. Конструкция, используемая для этого очень проста и удобна: звездочка в качестве названия свойства и пустой массив, который заполнится значениями "*" : []

Запрос Ответ
{
  "name": "Keith Emerson",
  "type": "/music/artist",
  "origin": {
    "type": "/location/country",
    "*": []
  }
}
У Англии много свойств

{
  "result": {
    "origin": {
      "fifa_code": [
        "ENG"
      ],
      "second_level_divisions": [
        "Rutland",
        "Leicestershire",
        "Leicester",
        "Derbyshire",
        "Derby",
        "Northamptonshire",
        "Nottinghamshire",
        "Nottingham",
        "Lincolnshire",
        "London Borough of Wandsworth",
        "London Borough of Bromley",
        "London Borough of Hounslow",
        "London Borough of Croydon",
        "London Borough of Sutton",
        "London Borough of Enfield",
        "London Borough of Hillingdon",
        "London Borough of Lambeth",
        "London Borough of Redbridge",
        "City of Westminster",
        "London Borough of Merton",
        "London Borough of Brent",
        "London Borough of Waltham Forest",
        "London Borough of Camden",
        "Royal Borough of Kingston upon Thames",
        "London Borough of Haringey",
        "London Borough of Bexley",
        "London Borough of Lewisham",
        "London Borough of Southwark",
        "London Borough of Harrow",
        "City of London",
        "London Borough of Newham",
        "London Borough of Barking and Dagenham",
        "London Borough of Richmond upon Thames",
        "London Borough of Barnet",
        "London Borough of Hammersmith and Fulham",
        "London Borough of Islington",
        "London Borough of Havering",
        "Royal Borough of Kensington and Chelsea",
        "Royal Borough of Greenwich",
        "London Borough of Tower Hamlets",
        "London Borough of Hackney",
        "London Borough of Ealing",
        "Lancashire",
        "Blackburn with Darwen",
        "Blackpool",
        "Greater Manchester",
        "Cheshire",
        "Cheshire West and Chester",
        "Borough of Halton",
        "Cheshire East",
        "Warrington",
        "Cumbria",
        "Merseyside",
        "Cornwall",
        "Isles of Scilly",
        "Wiltshire",
        "Borough of Swindon",
        "Devon",
        "Torbay",
        "Plymouth",
        "Bristol",
        "Somerset",
        "North Somerset",
        "Bath and North East Somerset",
        "Dorset",
        "Poole Borough Council",
        "Bournemouth Borough Council",
        "Gloucestershire",
        "South Gloucestershire",
        "Middlesbrough Borough Council",
        "Borough of Stockton-on-Tees",
        "Tyne and Wear",
        "Redcar and Cleveland",
        "North Yorkshire",
        "County Durham",
        "Borough of Darlington",
        "Borough of Hartlepool",
        "Northumberland",
        "Cambridgeshire",
        "Peterborough",
        "Essex",
        "Thurrock",
        "Southend-on-Sea",
        "Hertfordshire",
        "Suffolk",
        "Norfolk",
        "Bedford",
        "Luton",
        "Central Bedfordshire",
        "West Midlands",
        "Shropshire",
        "Telford and Wrekin",
        "Worcestershire",
        "Warwickshire",
        "Herefordshire",
        "Staffordshire",
        "Stoke-on-Trent",
        "South Yorkshire",
        "North East Lincolnshire",
        "East Riding of Yorkshire"
      ],
      "national_anthem": [],
      "permission": [
        "/boot/all_permission"
      ],
      "guid": [
        "#9202a8c04000641f8000000000014381"
      ],
      "name": [
        "England"
      ],
      "creator": [
        "/user/metaweb"
      ],
      "type": "/location/country",
      "languages_spoken": [
        "Old English",
        "Early Modern English",
        "English Language"
      ],
      "calling_code": [
        44
      ],
      "id": [
        "/en/england"
      ],
      "iso_alpha_3": [],
      "iso3166_1_alpha2": [],
      "currency_formerly_used": [],
      "gdp_nominal": [],
      "form_of_government": [
        "Constitutional monarchy",
        "Constituent country"
      ],
      "iso_numeric": [],
      "administrative_divisions": [
        "North East England",
        "North West England",
        "Yorkshire and the Humber",
        "West Midlands",
        "East Midlands",
        "East of England",
        "Greater London",
        "South East England",
        "South West England",
        "Little Gidding",
        "Dominion of New England",
        "Chilton",
        "Selby District",
        "Wakefield",
        "Dalvíkurbyggð",
        "Manor",
        "Upleadon"
      ],
      "third_level_divisions": [],
      "timestamp": [
        "2006-10-22T08:58:48.0043Z"
      ],
      "key": [
        "9316",
        "england",
        "ENG",
        "01Yg6fA3mG5Bf",
        "0080-5673",
        "190404",
        "66705302048946451041",
        "$0410$043D$0433$043B$0438$044F",
        "27953",
        "3003238",
        "713477",
        "Inglaterra",
        "$30A4$30F3$30B0$30E9$30F3$30C9",
        "8690",
        "Inghilterra",
        "10342",
        "Inglaterra",
        "England",
        "16627",
        "1023",
        "Angleterre",
        "4925",
        "$0410$043D$0433$043B$0438$044F",
        "Angleterre",
        "$0410$043D$0433$043B$0438$044F",
        "$0410$043D$0433$043B$0438$044F",
        "Inglaterra",
        "Inglaterra",
        "Inghilterra",
        "England",
        "$30A4$30F3$30B0$30E9$30F3$30C9",
        "England",
        "E92000001",
        "england$002F942213",
        "England",
        "$0625$0646$062C$0644$062A$0631$0627",
        "252",
        "281",
        "$067E$0627$062F$0634$0627$0647$06CC_$0627$0646$06AF$0644$0633$062A$0627$0646",
        "Anglija",
        "$C601$B780",
        "Anglia",
        "England",
        "England",
        "England",
        "Anglia",
        "13531",
        "$C601$AE38$B9AC",
        "England",
        "Engeland",
        "$0410$043D$0433$043B$0456$044F",
        "$0627$0646$062C$0644$062A$0631$0627",
        "Inggeris",
        "Anglia",
        "2353",
        "Anglija",
        "England",
        "$0130ngiltere",
        "Inggris",
        "England",
        "372",
        "England",
        "$0907$0902$0917$094D$0932$0945$0923$094D$0921",
        "$0627$0646$0643$0644$062A$0631$0629",
        "$0627$0646$062C$0644$062A$0640$0640$0631$0627",
        "Mellemengland",
        "GB-ENG",
        "$0907$0902$0917$094D$0932$0948$0923$094D$0921",
        "$0628$0625$0646$062C$0644$062A$0631$0627",
        "Engelske",
        "X$1EE9_Anh",
        "England",
        "$0391$03B3$03B3$03BB$03AF$03B1",
        "$0386$03B3$03B3$03BB$03BF$03B9",
        "Anh_C$00E1t_L$1EE3i",
        "Englanti",
        "Anglia",
        "Engelse",
        "$0E41$0E04$0E27$0E49$0E19$0E2D$0E31$0E07$0E01$0E24$0E29",
        "Anglija",
        "$0627$0644$0625$0646$062C$0644$064A$0632$064A",
        "11799",
        "$82F1$683C$5170",
        "Anglija",
        "England",
        "801",
        "$0625$0646$0643$0644$062A$0631$0647",
        "$0E0A$0E32$0E15$0E34$0E2D$0E31$0E07$0E01$0E24$0E29",
        "Anh",
        "Inglesa",
        "3812",
        "$05D0$05E0$05D2$05DC$05D9$05D4",
        "$0391$03B3$03B3$03BB$03AF$03B1",
        "$0627$0646$062C$0644$064A$0632$064A",
        "$0625$0646$0643$0644$062A$0631$0627",
        "England",
        "$0627$0646$06AF$0644$0633$062A$0627$0646",
        "$0625$0646$0643$0644$062A$0631$0651$0627",
        "Anglesa",
        "$0410$043D$0433$043B$0438$0439$0441$043A$0430"
      ],
      "official_language": [
        "English Language"
      ],
      "currency_used": [
        "UK £"
      ],
      "first_level_divisions": [
        "East Midlands",
        "Greater London",
        "North West England",
        "South West England",
        "North East England",
        "East of England",
        "West Midlands",
        "Yorkshire and the Humber",
        "South East England"
      ],
      "search": [],
      "fourth_level_divisions": [],
      "gdp_nominal_per_capita": [],
      "iso3166_1_shortname": [],
      "capital": [
        "London"
      ],
      "attribution": [
        "/user/metaweb"
      ],
      "fips10_4": [],
      "mid": [
        "/m/02jx1",
        "/m/071yqyc",
        "/m/071yqqb",
        "/m/07xyh0z"
      ],
      "internet_tld": [
        "uk"
      ]
    },
    "type": "/music/artist",
    "name": "Keith Emerson"
  }
}

Как лучше запрашивать объекты

Для тех, кто успел запутаться в скобочках, вот сводка по тому, как во Freebase можно запрашивать объекты:

Конструкция Её смысл
"свойство" : null
запрашивается значение свойства в виде одной строка. В качетсве этой строки будет выдано значение default-свойства объекта: value (для литералов) или name (для объектов). Если значением свойства является массив, выдается ошибка!
"свойство" : []
запрашивается массив строк. Результатом может быть пустой, массив, массив с одним значением или массив с несколькими значениями
"*" : []
на каждое свойство объекта запрашивается массив его значений
"свойство" : {}
запрашивается краткая информация об объекте. Для обычных объектов выдается их имя, идентификатор и тип
"свойство" : [{}]
запрашивается массив объектов в кратком виде. Работает аналогично {}, но для массивов
"свойство" : {вложенный запрос}
у объекта-значения свойства спрашивается все, что указано в запросе
"свойство" : [{вложенный запрос}]
вложенный запрос относится ко всем объектам в массиве значений свойств. Действует аналогично предыдущему для массивов.

Для начала достаточно. Понятное дело, что в MQL есть различные компараторы, регулярные выражения, всякие там И, ИЛИ и НЕ. Еще прекрасен язык Acre, который позволяет форматировать результаты запросов подобно тому, как это делается в Semantic MediaWiki. Ну и впереди рассказ о Dbpedia и Wikidata. Что бы вам было интересно почитать в первую очередь?

Автор: ganqqwerty

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js