Spec-Zone.ru › RethinkDB python

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

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 не предлагает существенного преимущества. Но вы можете использовать его для получения нескольких значений на одном уровне вложенности. Например, вы можете получить только номера телефонов Bob по работе и сотовой связи, но не домашний:

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

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

Или, телефон Bob по работе и Skype-адрес:

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

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

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

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

{
    'notes': [
        {
            'date': '2014-01-01T00:00:00+00:00' ,
            'from':  'John Doe'
        },
        {
            'date': '2014-02-02T00:00:00+00:00' ,
            '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 выше, и у Bob было 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/python/

Spec-Zone.ru

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