Spec-Zone.ru › RethinkDB javascript

Десятиминутное руководство по работе с RethinkDB и JavaScript

Перед началом:

  • Убедитесь, что вы установили RethinkDB—это займет всего минуту!
  • Также убедитесь, что вы установили драйвер JavaScript.
  • Прочитайте краткое руководство за тридцать секунд.

Запуск сервера

Для более подробного ознакомления, обязательно прочитайте краткое руководство.

Linux и OS X

Запустите сервер из терминала.

$ rethinkdb

Windows

Запустите сервер из командной строки Windows.

C:\Users\Slava\RethinkDB\>rethinkdb.exe

Импорт драйвера

Сначала запустите Node.js:

$ node

Затем импортируйте драйвер RethinkDB:

r = require('rethinkdb');

Теперь вы можете получить доступ к командам RethinkDB через r модуль.

Открытие соединения

При первом запуске RethinkDB сервер открывает порт для клиентских драйверов (28015 по умолчанию). Давайте откроем соединение:

var connection = null;
r.connect( {host: 'localhost', port: 28015}, function(err, conn) {
    if (err) throw err;
    connection = conn;
})

Переменная connection теперь инициализирована, и мы можем выполнять запросы.

Создание новой таблицы

По умолчанию RethinkDB создает базу данных test. Давайте создадим таблицу authors в этой базе данных:

r.db('test').tableCreate('authors').run(connection, function(err, result) {
    if (err) throw err;
    console.log(JSON.stringify(result, null, 2));
})

Результат будет:

{
    "config_changes": [
        <table configuration data>
    ],
    "tables_created": 1
}

(Поле config_changes содержит метаданные о только что созданной таблице; для более подробной информации, ознакомьтесь с командой tableCreate). Есть несколько моментов, которые следует отметить в этом запросе:

  • Во-первых, мы выбираем базу данных test с помощью команды db.
  • Затем мы добавляем команду tableCreate для создания фактической таблицы.
  • Наконец, мы вызываем run(connection, callback), чтобы отправить запрос на сервер.

Все запросы ReQL следуют этой общей структуре. Теперь, когда мы создали таблицу, давайте вставим некоторые данные!

Вставка данных

Давайте вставим три новых документа в таблицу authors.

r.table('authors').insert([
    { name: "William Adama", tv_show: "Battlestar Galactica",
      posts: [
        {title: "Decommissioning speech", content: "The Cylon War is long over..."},
        {title: "We are at war", content: "Moments ago, this ship received word..."},
        {title: "The new Earth", content: "The discoveries of the past few days..."}
      ]
    },
    { name: "Laura Roslin", tv_show: "Battlestar Galactica",
      posts: [
        {title: "The oath of office", content: "I, Laura Roslin, ..."},
        {title: "They look like us", content: "The Cylons have the ability..."}
      ]
    },
    { name: "Jean-Luc Picard", tv_show: "Star Trek TNG",
      posts: [
        {title: "Civil rights", content: "There are some words I've known since..."}
      ]
    }
]).run(connection, function(err, result) {
    if (err) throw err;
    console.log(JSON.stringify(result, null, 2));
})

Мы должны получить объект, похожий на этот:

{
    "unchanged": 0,
    "skipped": 0,
    "replaced": 0,
    "inserted": 3,
    "generated_keys": [
        "7644aaf2-9928-4231-aa68-4e65e31bf219",
        "064058b6-cea9-4117-b92d-c911027a725a",
        "543ad9c8-1744-4001-bb5e-450b2565d02c"
    ],
    "errors": 0,
    "deleted": 0
}

Сервер должен вернуть объект без ошибок и с тремя вставленными документами. Мы не указали первичные ключи (по умолчанию каждая таблица использует атрибут id для первичных ключей), поэтому RethinkDB сгенерировал их для нас. Сгенерированные ключи возвращаются через атрибут generated_keys.

Несколько моментов, которые следует отметить в этом запросе:

  • Каждое подключение устанавливает базу данных по умолчанию для использования в течение всего срока его существования (если вы не укажете её в connect, база данных по умолчанию будет test). Таким образом, мы можем опустить команду db('test') в нашем запросе. Мы больше не будем явно указывать базу данных, но если вы хотите добавить команду db в свои запросы, это не повлияет на работу.
  • Команда insert принимает один документ или массив документов, если вы хотите выполнять пакетные вставки. В этом запросе мы используем массив вместо выполнения трёх отдельных команд insert для каждого документа.

Извлечение документов

Теперь, когда мы вставили некоторые данные, давайте посмотрим, как мы можем запросить базу данных!

Все документы в таблице

Чтобы извлечь все документы из таблицы authors, мы можем просто выполнить запрос r.table('authors'):

r.table('authors').run(connection, function(err, cursor) {
    if (err) throw err;
    cursor.toArray(function(err, result) {
        if (err) throw err;
        console.log(JSON.stringify(result, null, 2));
    });
});

Результатом является массив из трёх ранее вставленных документов, вместе со сгенерированными значениями id.

Поскольку таблица может содержать большое количество документов, база данных возвращает объект курсора. По мере итерации по курсору сервер будет отправлять документы клиенту порциями по мере запроса. В нашем примере у нас всего три документа, поэтому мы можем безопасно извлечь все документы сразу. Функция toArray автоматически выполняет итерацию по курсору и помещает документы в массив JavaScript.

Фильтрация документов на основе условия

Давайте попробуем извлечь документ, где атрибут name установлен в значение William Adama. Мы можем использовать условие для фильтрации документов, прикрепив команду filter к концу запроса:

r.table('authors').filter(r.row('name').eq("William Adama")).
    run(connection, function(err, cursor) {
        if (err) throw err;
        cursor.toArray(function(err, result) {
            if (err) throw err;
            console.log(JSON.stringify(result, null, 2));
        });
    });

Этот запрос возвращает курсор с одним документом — записью для Уильяма Адама. Команда filter оценивает заданное условие для каждой строки в таблице и возвращает только соответствующие строки. Вот новые команды, которые мы использовали для составления условия выше:

  • r.row относится к текущему посещаемому документу.
  • r.row('name') относится к значению поля name посещаемого документа.
  • Команда eq возвращает true, если два значения равны (в данном случае, поле name и строка William Adama).

Давайте ещё раз воспользуемся filter для извлечения всех авторов, у которых более двух публикаций:

r.table('authors').filter(r.row('posts').count().gt(2)).
    run(connection, function(err, cursor) {
        if (err) throw err;
        cursor.toArray(function(err, result) {
            if (err) throw err;
            console.log(JSON.stringify(result, null, 2));
        });
    });

В этом случае мы используем предикат, который возвращает true только в том случае, если длина массива в поле posts больше двух. Этот предикат содержит две команды, которые мы ещё не видели:

  • Команда count возвращает размер массива.
  • Команда gt возвращает true, если значение больше указанного значения (в данном случае, если количество публикаций больше двух).

Извлечение документов по первичному ключу

Мы также можем эффективно извлекать документы по их первичному ключу, используя команду get. Мы можем использовать один из идентификаторов, сгенерированных в предыдущем примере:

r.table('authors').get('7644aaf2-9928-4231-aa68-4e65e31bf219').
    run(connection, function(err, result) {
        if (err) throw err;
        console.log(JSON.stringify(result, null, 2));
    });

Поскольку первичные ключи уникальны, команда get возвращает единственный документ. Таким образом, мы можем извлечь документ непосредственно, не преобразуя курсор в массив.

Узнайте больше о том, как RethinkDB может эффективно извлекать документы с помощью вторичных индексов.

Потоки в реальном времени

Вы можете пропустить этот раздел, если пока не хотите изучать потоки в реальном времени. Вы всегда можете вернуться и начать подписку на поток позже.

RethinkDB переворачивает традиционную архитектуру баз данных, предоставляя новый интересный механизм доступа — вместо опроса на изменения, разработчик может указать RethinkDB непрерывно отправлять обновлённые результаты запросов в приложения в реальном времени.

Чтобы начать поток, откройте новый терминал и откройте новое подключение к RethinkDB. Затем выполните следующий запрос:

r.table('authors').changes().run(connection, function(err, cursor) {
    if (err) throw err;
    cursor.each(function(err, row) {
        if (err) throw err;
        console.log(JSON.stringify(row, null, 2));
    });
});

Теперь вернитесь в свой первый терминал. В следующих двух разделах мы будем обновлять и удалять некоторые документы. По мере выполнения этих команд поток будет отправлять уведомления в вашу программу. В втором терминале код выше выведет следующие сообщения:

{
  "new_val": {
    "id": "1d854219-85c6-4e6c-8259-dbda0ab386d4",
    "name": "Laura Roslin",
    "posts": [...],
    "tv_show": "Battlestar Galactica",
    "type": "fictional"
  },
  "old_val": {
    "id": "1d854219-85c6-4e6c-8259-dbda0ab386d4",
    "name": "Laura Roslin",
    "posts": [...],
    "tv_show": "Battlestar Galactica"
  }
}

RethinkDB будет уведомлять вашу программу обо всех изменениях в таблице authors и будет включать старое и новое значения каждого изменённого документа. Ознакомьтесь с документацией по changefeeds, чтобы узнать больше о том, как использовать потоки в реальном времени в RethinkDB.

Обновление документов

Давайте обновим все документы в таблице authors и добавим поле type , чтобы отметить, что все авторы до сих пор являются вымышленными:

r.table('authors').update({type: "fictional"}).
    run(connection, function(err, result) {
        if (err) throw err;
        console.log(JSON.stringify(result, null, 2));
    });

Поскольку мы изменили три документа, результат должен выглядеть так:

{
    "unchanged": 0,
    "skipped": 0,
    "replaced": 3,
    "inserted": 0,
    "errors": 0,
    "deleted":0
}

Обратите внимание, что мы сначала выбрали каждого автора в таблице, а затем прикрепили команду update к концу запроса. Мы также могли бы обновить подмножество документов, отфильтровав таблицу сначала. Давайте обновим запись Уильяма Адама, чтобы отметить, что он имеет звание адмирала:

r.table('authors').
    filter(r.row("name").eq("William Adama")).
    update({rank: "Admiral"}).
    run(connection, function(err, result) {
        if (err) throw err;
        console.log(JSON.stringify(result, null, 2));
    });

Поскольку мы обновили только один документ, мы получим этот объект:

{
    "unchanged": 0,
    "skipped": 0,
    "replaced": 1,
    "inserted": 0,
    "errors": 0,
    "deleted": 0
}

Команда update позволяет изменять существующие поля в документе, а также значения внутри массивов. Предположим, археологи Star Trek обнаружили новую речь Жана-Люка Пикара, которую мы хотели бы добавить к его публикациям:

r.table('authors').filter(r.row("name").eq("Jean-Luc Picard")).
    update({posts: r.row("posts").append({
        title: "Shakespeare",
        content: "What a piece of work is man..."})
    }).run(connection, function(err, result) {
        if (err) throw err;
        console.log(JSON.stringify(result, null, 2));
    });

После обработки этого запроса RethinkDB добавит дополнительную публикацию к документу Жана-Люка Пикара.

Ознакомьтесь со справочником по API для получения многих других операций с массивами, доступных в RethinkDB.

Удаление документов

Предположим, мы хотели бы обрезать нашу базу данных и удалить каждый документ с менее чем тремя публикациями (извините, Лора и Жан-Люк):

r.table('authors').
    filter(r.row('posts').count().lt(3)).
    delete().
    run(connection, function(err, result) {
        if (err) throw err;
        console.log(JSON.stringify(result, null, 2));
    });

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

{
    "unchanged": 0,
    "skipped": 0,
    "replaced": 0,
    "inserted": 0,
    "errors": 0,
    "deleted": 2
}

Узнать больше

Хотите продолжить обучение? Ознакомьтесь с документацией:

  • Прочитайте введение в RQL, чтобы глубже изучить концепции ReQL.
  • Узнайте, как использовать map-reduce в RethinkDB.
  • Изучите, как использовать соединения таблиц в RethinkDB.
  • Перейдите к справочнику по рецептам и ознакомьтесь с десятками примеров общих запросов RethinkDB.

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

Spec-Zone.ru

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