Spec-Zone.ru › RethinkDB ruby

Доступ к вложенным полям

Nested Fields Illustration

Документ ReQL представляет собой JSON-объект: набор пар ключ-значение, в котором каждое значение может быть отдельным значением, списком значений или другим набором пар ключ-значение. Когда значение поля содержит дополнительные поля, мы называем их вложенными полями.

Рассмотрим таблицу пользователей с контактной информацией и списком заметок для каждого пользователя в следующем формате:

{
  :id => 10001,
  :name => "Bob Smith",
  :contact => {
    :phone => {
      :work => "408-555-1212",
      :home => "408-555-1213",
      :cell => "408-555-1214"
    },
    :email => {
      :work => "bob@smith.com",
      :home => "bobsmith@gmail.com",
      :other => "bobbys@moosecall.net"
    },
    :im => {
      :skype => "Bob Smith",
      :aim => "bobmoose",
      :icq => "nobodyremembersicqnumbers"
    }
  },
  :notes => [
    {
      :date => r.time(2014,1,1,'Z'),
      :from => "John Doe",
      :subject => "My name is even more boring than Bob's"
    },
    {
      :date => r.time(2014,2,2,'Z'),
      :from => "Bob Smith Sr",
      :subject => "Happy Second of February"
    }
  ]
}

Контактная информация является вложенной, как пути в файловой системе.

contact → phone → work → 408-555-1212

Вы можете получить значение конкретного поля, используя оператор [] последовательно, чтобы «проникнуть внутрь» вложенности документа:

> r.table('users').get(10001)['contact']['phone']['work'].run(conn)

'408-555-1212'

Большинство команд, принимающих строку имени поля или синтаксис [] выше, также поддерживают вложенный синтаксис в стиле JSON:

> r.table('users').get(10001).pluck(
  {'contact' => {'phone' => 'work'}}
).run(conn)

{
  'contact' => {
    'phone' => {
      'work' => '408-555-1212'
    }
  }
}

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

> r.table('users').get(10001).pluck(
  {'contact' => {'phone' => ['work', 'cell']}}
).run(conn)

{
  'contact' => {
    'phone' => {
      'cell' => '408-555-1214',
      'work' => '408-555-1212'
    }
  }
}

Или, рабочий телефон и Skype Боба:

> r.table('users').get(10001).pluck(
  {'contact' => [{'phone' => 'work', 'im' => 'skype'}]}
).run(conn)

{
  'contact' => {
    'im' => {
      'skype' => 'Bob Smith'
    },
    'phone' => {
      'work' => '408-555-1212'
    }
  }
}

И это ещё не всё! Вы можете фильтровать поля объектов внутри списка. Предположим, вам нужны только даты и отправители заметок Боба:

> r.table('users').get(10001).pluck(
  {'notes' => ['date', 'from']}
).run(conn)

{
  'notes' => [
    {
      'date' => 2014-01-01 00:00:00 +0000 ,
      'from' =>  'John Doe'
    },
    {
      'date' => 2014-02-02 00:00:00 +0000 ,
      'from' =>  'Bob Smith Sr.'
    }
  ]
}

Если вы запросите вложенное поле, которого не существует, вы получите пустой объект или массив (это не то же самое, что и nil значение):

> r.table('users').get(10001).pluck(
  {'contact' => [{'phone' => 'work', 'im' => 'msn'}]}
).run(conn)

{
  'contact' => {
    'im' => { },
    'phone' => {
      'work' => '408-555-1212'
    }
  }
}

Обратите внимание, что это поведение также справедливо при извлечении данных из списков. Если вы извлекли subject из notes выше, а у Боба было 10 заметок, 3 из которых не содержали поля subject, вы по-прежнему получите список из 10 объектов: 7 из них будут {subject => <text>}, а 3 — пустыми, то есть { }.

Кроме того, ещё один момент: синтаксис вложенных полей не гарантирует идентичных схем между документами, которые он возвращает. Возможна ситуация, когда путь соответствует объектам с различными схемами, как показано в этом простом примере.

> r.expr([
  {
    'a' => {
      'b' => 1,
      'c' => 2
    }
  },
  {
    'a' => [
      {
        'b' => 1,
        'c' => 2
      }
    ]
  }
]).pluck({'a' => {'b' => true}}).run(conn)

[
  {
    'a' => {
      'b' => 1
    }
  },
  {
    'a' => [
      {
        'b' => 1
      }
    ]
  }
]

© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/docs/nested-fields/ruby/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API