Конструирование и выполнение запросов на чтение баз знаний и данных

В документе описывается технология формирования и выполнения запросов к графовым базам знаний и данных, формируемым по используемой на платформе 2-уровневой модели информационных ресурсов.
В настоящее время поддерживаются только запросы на чтение.

Введение

Механизмы задания и выполнения запросов к базам знаний и данных, сформированных в виде иерархических сетей, формируемых на основе 2-уровневой модели порождения информации, базируются на механизмах, использованных для формирования и проверке контекстных условий и ограничений целостности. Разнице между механизмами заключается в том, что в данном случае во главу угла ставится вычисление некоторого терма, значение которого является результатом запроса, а в качестве вспомогательного механизма работает логическая формула (которая является основой у контекстных условий).

Работа с запросом состоит из двух этапов:
  1. формирование – инженер по знаниям (или эксперт, или разработчик агента/решателя) формирует запрос к базе/-ам знаний определённого типа (созданным на основе некоторой метаинформации или их группы)
  2. выполнение – исполнение запроса для выбранного информационного ресурса/-ов (с сохранением полученных данных) и использование результата (просмотра и т.п.)
Оба этапа осуществляются специальным платформенным интерфейсным решателем «Конструктор запросов» (используется по умолчанию для открытия инфоресурсов, сформированных по метаинформации "Язык описания запросов" - см. ниже).
а также может быть выполнена агентом в рамках кода его БП (см. Выполнение запросов на чтение баз знаний и данных из кода агентов в разделе "Разработка").

Формирование запросов

Запрос на чтение в общем виде имеет следующую структуру: Задание формальных параметров запроса состоит в задании имени каждого параметра и для "инфоресурса" – установки ссылки на онтологию исследуемой базы знаний или данных, а для "данного" – указания типа его значения. Впоследствии указанной информации должны соответствовать значения фактических параметров (см. в след. раздел).

Задание тела запроса состоит в формировании так называемого терма – некоторого вычислимого данного, для которого задаётся (математическая) формула вычисления. В её состав могут входить иные термы и предикаты (логические формулы), формируемые с использованием терминов некоторой модели онтологии (или нескольких онтологий), то есть с использованием вершин некоторого (одного или нескольких) инфоресурса(-ов) типа "метаинформация". Для запроса также могут быть заданы (а могут и отсутствовать) параметры, значения которых "подставляются" в тело запроса перед началом каждого выполнения, что позволяет "подставлять" в запрос какие-то термины действительности или знаний, выбираемые, например, из меток вершин базы знаний или данных. Язык задания запросов задан в информационном ресурсе "Язык описания запросов" (типа "метаинформация"), который расположен в общем Фонде (раздел "Платформа IACPaaS", папка "Ядро платформы"). Он позволяет формировать в одном инфоресурсе несколько запросов – с целью создания библиотек запросов. Для каждого запроса помимо его "тела" этот язык также специфицирует структуру его "выполнений" (запрос может исполняться несколько раз, с определёнными наборами значений фактических параметров), которая включает 2 подраздела – описание структуры для задания используемого набора значений фактических параметров запроса и описание структуры сохраняемых результатов выполнения (запрос с определённым набором значений параметров может исполняться несколько раз, так как содержимое базы знаний меняется). Сформированные информационные ресурсы с запросами существуют сами по себе (не требуют прикрепления к каким-то другим информационным ресурсам для возможности быть исполненными.

Для формирования запросов, зарегистрированный пользователь должен: Структура терма (в описании "тела" запроса) заимствуется из области знаний «Математика» с некоторыми упрощениями (присутствует не весь перечень логических, арифметических, теоретко-множественных и т.п. операций) и дополнениями (для осуществления навигации по информационным ресурсам и работы с их содержимым). Иногда вместо более общего "терма" в формуле используется его частный вид – "терм-число", "терм-строка", "терм-множество" – для получения значения определённого типа. В общем случае терм может иметь значение типа "вершина базы знаний", "строка", "целое", "вещественное", "логическое", "темпоральное" (дата и время), "бинарные данные", "множество" (с элементами любого из перечисленных типов). Такой тип указан в описании результата вычисления запроса (см. далее).

Для вычисления значения терма используется одно из следующих выражений: Переменная задаётся в виде пары "имя" – "область возможных значений" (ОВЗ), где ОВЗ задаётся как подграф "имени" одним из следующих способов (соответствующих заданию терма-множества): Задание ОВЗ переменной через "множество соответствующих мета-пути вершин" (для формирования ОВЗ в виде множества вершин графа, представляющего базу знаний) заключается в общем случае в указании последовательности метапонятий, по которым нужно перемещаться (в соответствии с моделью двухуровневого формирования инфоресурсов) по графу, представляющему базу знаний, вверх или вниз от некоторого начального множества вершин, заменяя это множество на новое, получаемое на очередном шаге. Множество вершин, полученное на финальном шаге составляет искомую ОВЗ.

Задание выполняется следующим образом:
  1. задаётся начальное множество вершин – под создаваемым нетерминалом "начало пути":
  2. при необходимости задаётся "продолжение пути", где по очереди (по шагам) указываются ссылками метапонятия, по которым нужно переходить от каждого из полученных ранее понятий по графу, представляющему базу знаний, вверх (указывается специальной вершиной в описании шага) или вниз (выполняется по умолчанию), при этом получаемые множества потомков (или предков) объединяются, формируя результирующее для шага множество
  3. при необходимости задаётся "окончание пути", где по очереди (по шагам) указываются ссылками метапонятия, по которым нужно переходить от каждого из полученных ранее понятий по графу, представляющему базу знаний, вверх (указывается специальной вершиной в описании шага) или вниз (выполняется по умолчанию), при этом получаемые множества потомков (или предков) объединяются, формируя результирующее для шага множество; при этом также для перехода от последнего шага "продолжения пути" к первому шагу "конца пути" от каждой из полученных ранее вершин
При спецификации начала пути здесь (в отличии от такой спецификации при задании контекстных условий) необходимо указать, в рамках какого инфоресурса нужно выбирать вершины. Для этого необходимо выполнить порождение по метапонятию "область выбора", при этом метка создаваемой вершины должна формироваться как зависимый клон от имени формального параметра (инфоресурса).

Терм типа "соответствующая мета-пути вершина" служит для выбора из информационного ресурса единственной вершины, доступной, начиная с заданной, по некоторому мета-пути. Его задание аналогично указанию мета-пути для "множество доступных по мета-пути вершин", а при интерпретации всегда выполняется проверка того, что на каждом шаге извлекается лишь одна вершина из исследуемого информационного ресурса.

Терм типа "результат выполнения внешнего запроса" служит для обращения к внешнему программному обеспечению с целью получения данных. При его описании указывается адрес удалённого сервера (http...), имена и значения параметров (термы-строки или -числа). Полученный результат по умолчанию интерпретируется как строка (UTF-8), а если его необходимо интерпретировать как двоичные данные - необходимо создать вершину "двоичный ответ".

Кванторные конструкции делятся на: Типы логической формулы, применяемой при вычислении: Более подробно об используемых конструкциях можно узнать в статье Т.Л. Гаврилова, А.С. Клещев, Внутренняя модель математической практики для систем автоматизированного конструирования доказательств теорем. Ч.2. Модель математического диалекта, Пробл. управл., 2006, выпуск 5, 68–73.

Более подробно о конструировании регулярных выражение можно узнать, например, тут (раздел Summary of regular-expression constructs) и тут.

Ниже приведено упрощённое представления Языка описания запросов (в нотации текстового представления информационных ресурсов):
Язык описания запросов
{
  ~setmm ~new запрос {
    ~new формальные параметры {
      ~new инфоресурсы {
        ~setmm ~new имя параметра {
          ~one ~ref -> инфоресурс$; #необходимо сослаться на корень онтологии
      }}
      ~new данные {
        ~setmm ~new имя параметра ~ALT{
          ~new ["вершина"]
          ~new ["строковое"] 
          ~new ["целое"] 
          ~new ["вещественное"] 
          ~new ["логическое"] 
          ~new ["дата и время"] 
          ~new ["бинарные данные"] 
          ~new множество ~ALT{
            ~new -> .../формальные параметры/данные/имя параметра/вершина;
            ~new -> .../формальные параметры/данные/имя параметра/строковое;
            ~new -> .../формальные параметры/данные/имя параметра/целое;
            ~new -> .../формальные параметры/данные/имя параметра/вещественное;
            ~new -> .../формальные параметры/данные/имя параметра/логическое;
            ~new -> .../формальные параметры/данные/имя параметра/дата и время;
            ~new -> .../формальные параметры/данные/имя параметра/бинарные данные;
            ~new -> .../формальные параметры/данные/имя параметра/множество;
    }}}}
    ~new тело запроса {
      ~new терм ~ALT{
        ~one ~ref переменная {
          ~new терм-множество ~ALT{
            ~new множество соответствующих мета-пути вершин {
              ~new начало пути ~ALT{
                ~new вершина {
                  ~one ~ref -> инфоресурс$; #сделайте ссылку на вершину в метаинформации (в случае запроса – в формальном параметре-инфоресурсе)
                  ~onemm ~clone область выбора [str] #в качестве значения клонируйте имя формального параметра – инфоресурса (при его наличии)
                }
                ~one ~ref -> переменная;
              }
              ~copymm ~new продолжение пути {
                ~seq элемент пути {
                  ~one ~ref -> инфоресурс$;
                  ~copymm  ["вверх"] 
              }}
              ~copymm ~new конец пути {
                ~seq -> элемент пути;
            }}
            ~new экстенсионально заданное множество {
              ~seq элемент множества {
                ~new -> терм;
            }}
            ~new пересечение множеств {
              ~seq множество {
                ~new -> терм-множество;
            }}
            ~new объединение множеств {
              ~seq -> множество;
            }
            ~new разность множеств {
              ~new уменьшаемое множество {
                ~new -> терм-множество;
              }
              ~new вычитаемое множество {
                ~new -> терм-множество;
            }}
            ~new квантор интенсиональности {
              ~proxy -> Язык описания контекстных условий$/.../переменная и формула;
            }
            ~new квантор объединения {
              ~proxy переменная и терм-множество {
                ~one ~new -> переменная;
                ~new -> терм-множество;
            }}
            ~new квантор пересечения{
              ~proxy -> переменная и терм-множество;
            }
            ~new условный терм {
              ~copymm ~new выражение { #задаётся для типа SWITCH-CASE
                ~new -> терм;
              }
              ~seq альтернатива {
                ~ALT {
                  ~new -> Язык описания контекстных условий$/.../формула; #задаётся для if / elseif
                  значение { #задаётся для case
                    ~new -> терм;
                }}
                ~new заключение {
                  ~new -> терм;
              }}
              иначе {
                ~new -> терм;
            }}
            ~new область возможных значений переменной {
              ~one ~ref -> переменная;
            }
            ~new все вершины {
              ~onemm ~clone -> область выбора; #c в качестве значения клонируйте имя формального параметра – инфоресурса (при его наличии)
        }}}
        ~proxy термы, связанные с множествами ~ALT{
          ~new -> множество соответствующих мета-пути вершин;
          ~new -> экстенсионально заданное множество;
          ~proxy действия над множествами ~ALT{
            ~new -> объединение множеств;
            ~new -> пересечение множеств;
            ~new -> разность множеств;
            ~new мощность множества {
              ~new -> терм-множество;
            }
            ~new sup {
              ~new -> терм-множество;
            }
            ~new inf {
              ~new -> терм-множество;
        }}}
        ~proxy арифметические термы ~ALT{
          ~new сумма {
            ~seq слагаемое {
              ~new терм-число ~ALT{
                ~new -> мощность множества;
                ~new -> sup;
                ~new -> inf;
                ~proxy арифметические термы;
                ~new квантор суммирования {
                  ~proxy переменная и терм-число {
                    ~one ~new -> переменная;
                    ~new -> терм-число;
                  }
                }
                ~new квантор умножения {
                  ~proxy -> переменная и терм-число;
                }
                ~new -> условный терм;
                ~new метка вершины {
                  ~new -> терм;
                }
                целочисленная константа [int]
                вещественная константа [real]
                ~proxy именованная математическая постоянная ~ALT{
                   ["π"] 
                   ["τ"] 
                   ["e"] 
          }}}}
          ~new произведение  {
            ~seq сомножитель {
              ~new -> терм-число;
          }}
          ~new разность {
            ~new уменьшаемое {
              ~new -> терм-число;
            }
            ~new вычитаемое {
              ~new -> терм-число;
          }}
          ~new частное {
            ~new делимое {
              ~new -> терм-число;
            }
            ~new делитель {
              ~new -> терм-число;
          }}
          ~new возведение в степень {
            ~new основание {
              ~new -> терм-число;
            }
            ~new показатель {
              ~new -> терм-число;
          }}
          ~new абсолютная величина {
            ~new -> терм-число;
        }}
        ~proxy кванторные конструкции ~ALT{
          ~new йота-оператор {
            ~proxy -> Язык описания контекстных условий$/.../переменная и формула;
          }
          ~new -> квантор интенсиональности;
          ~new -> квантор объединения;
          ~new -> квантор пересечения;
          ~new -> квантор суммирования;
          ~new -> квантор умножения;
          ~new квантор конкатенации {
            ~proxy переменная и терм-строка {
              ~one ~new -> переменная;
              ~new терм-строка ~ALT{
                ~new -> метка вершины;
                строковая константа [str]
                двоичная константа [blob]
                ~new -> условный терм;
                ~new -> строковое представление;
          }}}
          ~new квантор преобразования множества {
            ~proxy переменная и терм {
              ~one ~new -> переменная;
              ~new -> терм;
        }}}
        ~new -> условный терм;
        ~new -> метка вершины;
        ~proxy константы ~ALT{
          ~new  ["пустое множество"]
          -> целочисленная константа;
          -> вещественная константа;
          логическая константа [bool]
          -> строковая константа;
          темпоральная константа [date]
          -> двоичная константа;
          ~new ["текущий момент"] 
        }
        ~new вершина-оригинал {
          ~one ~ref -> переменная;
        }
        ~new конкатенация {
          ~seq операнд {
            ~new -> терм-строка;
        }}
        ~clone параметр [str]
        ~new соответствующая мета-пути вершина {
          ~proxy -> множество соответствующих мета-пути вершин;
        }
        ~new результат выполнения внешнего запроса {
          ~new адрес [str]
          ~setmm ~new параметр #имя параметра
          ~ALT{
            ~new -> терм-число;
            ~new -> терм-строка;
          }
          ~copymm ~new ["двоичный ответ"] #задаётся если результат нужно интерпретировать не как строку, а как двоичные данные
        }
        ~new строковое представление {
          new -> терм;
    }}
    ~copymm ~new выполнения {
      ~listmm ~new выполнение {
        ~new фактические параметры {
          ~new инфоресурсы {
            ~setmm ~clone имя фактического параметра { #имя склонируйте от имени формального параметра запроса
              ~one ~ref -> инфоресурс$;
          }}
          ~new данные {
            ~setmm ~clone параметр ~ALT{
              ~one ~ref -> инфоресурс$;
              ~new строковое [str]
              ~new целое [int]
              ~new вещественное [real]
              ~new логическое [bool]
              ~new дата и время [date]
              ~new бинарные данные [blob]
              ~new множество ~ALT{
                ~list ~ref -> инфоресурс$;
                ~list ~new -> .../фактические параметры/данные/параметр/строковое;
                ~list ~new -> .../фактические параметры/данные/параметр/целое;
                ~list ~new -> .../фактические параметры/данные/параметр/вещественное;
                ~list ~new -> .../фактические параметры/данные/параметр/логическое;
                ~list ~new -> .../фактические параметры/данные/параметр/дата и время;
                ~list ~new -> .../фактические параметры/данные/параметр/бинарные данные;
                ~seq  ~new -> .../фактические параметры/данные/параметр/множество;
              }
        }}}
        ~new результаты {
          ~seqmm результат {
            ~proxy -> .../фактические параметры/данные/параметр;
}}}}}}

Следует отметить, что обычно запрос формулируется на естественном языке как последовательность действий, а в случае его формального представления на предложенном языке на более верхнем уровне формируемого графа представляются наиболее поздние (по выполнению) действия, а в глубине – самые первые (что характерно для функционального программирования).

Выполнение запросов

Выполнение запроса возможно только, если полны три подграфа в исполняемом запросе: Выполнить запрос можно: Исполнение запроса платформой состоит в его интерпретации путём вычисления термов и формул на основе заданных значений параметров и содержимого базы (баз) знаний и сохранение полученного значения в поддерево выполнений.

Процесс вычисления в Конструкторе запросов запроса состоит в:
  1. формировании пользователем вершины "выполнения" у запроса (если таковой ещё нет)
  2. формировании под вершиной "выполнения" пользователем новой вершины по метапонятию "выполнение" (с заданием некоторого имени, отражающего суть этого выполнения) – при необходимости задания нового массива входных данных, а при отсутствии такой необходимости можно использовать ранее созданную вершину с таким метапонятием
  3. формировании ниже описания значений фактических параметров (для инфоресурсов и данных, если они есть) – причём все имена параметров должны быть зависимо-склонированы от имён формальных параметров, указываемые ссылками на корень целевые инфоресурсы должны быть сформированы по указанным в формальных параметрах метаинформациям, а значения данных должны соответствовать указанным в формальных параметрах типам
  4. формировании под вершиной "выполнения" пользователем новой вершины по метапонятию "результаты", а в случае повторного использования выполнений некоторого запроса можно использовать ранее созданную вершину с таким метапонятием
  5. отправке пользователем команды на вычисление результата запроса (по нажатию порождения "результат")
  6. выполнении конструктором вычисления результата запроса (это может быть длительный процесс, возможно, окно конструктора станет неактивно)
  7. отображении результата проверки (в момент, когда пользователь, обновит состояние конструктора, а результат проверки уже получен)

Примеры

Рассмотрим предметную область Медицина.

Пример 1

Одной из баз знаний является База наблюдений. В этом инфоресурсе описываются группы признаков, их имена и указываются их допустимые значения. Для изучения наполнения базы наблюдений пользователь может сформировать запрос на извлечение всех признаков, находящихся в некоторой группе, например, "Жалобы":

Ниже представлена модель онтологии базы наблюдений:
Онтология наблюдений
{
  ~setmm ~new группа признаков
  {
    ~setmm ~new -> группа признаков;
    ~setmm ~new признак
    {
      ~one ~new нижняя граница [real]
      ~one ~new верхняя граница [real]
    }
  }
}
Для описания запросов формируется отдельный целевой инфоресурс (по метаинформации "Язык описания запросов").

Сформулируем запрос более формально: найти все вершины с метапонятием "признак" под всеми вершинами с меткой "Жалобы" и метапонятием "группа признаков". Написание такого запроса делится на три части:
  1. указание на необходимость нахождения всех вершин с метапонятием "группа признаков"
  2. извлечь из них все те, у которых метка = "Жалобы"
  3. под всеми найденными вершинами найти все вершины с метапонятием "признак" (на любом "расстоянии" от вершин "Жалобы")
  4. вернуть объединение полученных множеств
Такой запрос с применением предложенного языка задаётся "снизу-вверх" следующим образом:
Примеры запросов <<< Платформа IACPaaS/Ядро платформы/Язык описания запросов
{
  запрос [Извлечь жалобы из БН] {
    формальные параметры {
      инфоресурсы {
        имя параметра [База Наб] {
          инфоресурс [-> Онтология базы медицинской терминологии и наблюдений$;]
      }}
      данные {}
    }
    тело запроса {
      терм {
        квантор объединения {
          терм-множество {
            множество соответствующих мета-пути вершин {
              начало пути {
                переменная [жалобы] {
                  терм-множество {
                    квантор интенсиональности {
                      формула {
                        равенство {
                          левая часть {
                            терм {
                              метка вершины {
                                терм {
                                  переменная [группы признаков] {
                                    терм-множество {
                                      множество соответствующих мета-пути вершин {
                                        начало пути {
                                          вершина {
                                            инфоресурс [-> Онтология базы медицинской терминологии и наблюдений$/.../Группа признаков;]
                                            область выбора [<- Примеры запросов$/Извлечь жалобы из БН/формальные параметры/инфоресурсы/База Наб;] 
                          }}}}}}}}}
                          правая часть {
                            терм {
                              строковая константа ["Жалобы"] 
                      }}}}
                      переменная [-> Примеры запросов$/Извлечь жалобы из БН/тело запроса/терм/квантор объединения/терм-множество/множество соответствующих мета-пути вершин/начало пути/жалобы/терм-множество/квантор интенсиональности/формула/равенство/левая часть/терм/метка вершины/терм/группы признаков;]
              }}}}
              конец пути {
                элемент пути [1] {
                  инфоресурс [-> Онтология базы медицинской терминологии и наблюдений$/.../Группа признаков/Признак;]
          }}}}
          переменная [-> Примеры запросов$/Извлечь жалобы из БН/тело запроса/терм/квантор объединения/терм-множество/множество соответствующих мета-пути вершин/начало пути/жалобы;]
    }}}
    выполнения { ... }
  }
}


Особенности составления данного запроса следующие:

К особенностям исполнения запроса можно отнести, то что его результатом является "множество" (вершина, создаваемая под вершиной "результат"), под которым сформированы ссылки на искомые вершины базы наблюдений (в составленном примере база наблюдений содержит 2849 признаков, а запрос вычислил 205, находящихся в группе "Жалобы").

Ниже представлен интерфейс Конструктора запросов с телом запроса, и его выполнением.


Рис.1. Поиск всех "Жалоб"

Пример 2

Другой задачей, стоящей перед мед. персоналом, может быть вычисление коэффициентов, характеризующих пациентов. Рассмотрим вычисление так называемого "Индекса массы тела". Формула для его вычисления следующая: ИМТ = вес / рост².

Сформулируем запрос на это вычисление формально: разделить вес на произведение роста и роста.

Такой запрос задаётся так:
Примеры запросов <<< Платформа IACPaaS/Ядро платформы/Язык описания запросов
{
  запрос [ИМТ] {
    формальные параметры {
      инфоресурсы {}
      данные {
        имя параметра [вес] {
           ["вершина"] 
        }
        имя параметра [рост] {
           ["вершина"] 
    }}}
    тело запроса {
      терм {
        частное {
          делимое {
            терм-число {
              метка вершины {
                терм {
                  параметр [<- Примеры запросов$/ИМТ/формальные параметры/данные/вес;] 
          }}}}
          делитель {
            терм-число {
              произведение {
                сомножитель [1] {
                  терм-число {
                    метка вершины {
                      терм {
                        параметр [<- Примеры запросов$/ИМТ/формальные параметры/данные/рост;] 
                }}}}
                сомножитель [2] {
                  терм-число {
                    метка вершины {
                      терм {
                        параметр [<- Примеры запросов$/ИМТ/формальные параметры/данные/рост;] 
    }}}}}}}}}}
    выполнения {...}
}}


Особенности составления данного запроса следующие: Ниже представлен интерфейс Конструктора запросов с телом запроса, и его выполнением.


Рис.2. Вычисление "ИМТ"


Пример 3

Ещё одной задачей, которая имеет более широкую область применения, является поиск вершин в базе знаний. В общем случае можно сформулировать запрос на поиск вершин так: "среди всех вершин инфоресурса выбрать те, метка которых содержит заданную строку (без учёта регистра)".

Сформулируем запрос на такую выборку формально (выбрав искомую подстроку "боль"): перебрать все вершины заданного инфоресурса и вернуть такое их подмножество, для каждой вершины которого её метка соотетствует регулярому выражению, описывающему правило "включает подстроку 'боль' независимо от регистра букв".

Такой запрос (исключая результаты выполнений) задаётся так:
Примеры запросов <<< Платформа IACPaaS/Ядро платформы/Язык описания запросов
{
  запрос [поиск боль] {
    формальные параметры {
      инфоресурсы {
        имя параметра [ИР] {
          инфоресурс [-> инфоресурс$;]
      }}
      данные {}
    }
    тело запроса {
      терм {
        квантор интенсиональности {
          переменная [вершина из ИР] {
            терм-множество {
              все вершины {
                область выбора [<- Примеры запросов$/поиск боль/формальные параметры/инфоресурсы/ИР;] 
          }}}
          формула {
            соответствие регулярному выражению {
              строка {
                терм-строка{
                  метка вершины{
                    терм {
                      переменная [-> Примеры запросов$/поиск боль/тело запроса/терм/квантор интенсиональности/вершина из ИР;]
              }}}}
              регулярное выражение [".*(Б|б)(О|о)(Л|л)(Ь|ь).*"] 
    }}}}}
    выполнения {
      выполнение [1] {
        фактические параметры {
          инфоресурсы {
            имя фактического параметра [<- Примеры запросов$/поиск боль/тело запроса/терм/квантор интенсиональности/вершина из ИР/терм-множество/все вершины/ИР;] {
              инфоресурс [-> База медицинской терминологии и наблюдений$;]
          }}
          данные {}
        }
        результаты {...}
}}}}

Особенности составления данного запроса следующие: